您的位置:首页 > 产品设计 > UI/UE

java核心API之String,StringBuffer和StringBuilder以及equals与==的区别和联系

2015-12-24 15:35 886 查看
String类:

构造方法:

[code]A:String() 空构造创建字符串。
B:String(byte[] bytes) 把字节数组转成字符串
C:String(byte[] bytes, int index, int length) 把字节数组的一部分转成字符串
D:String(char[] value) 把字符数组转成字符串
E:String(char[] value, int index, int count) 把字符数组的一部分转成字符串
F:String(String original) 把字符串转成字符串


字符串的拼接:

[code]String s = new String();
 System.out.println("s:" + s); // 说明重写了toString()方法 不然会打印地址值
String s="hello";     s+="world";  字符串的拼接非常耗费内存"hello" "world"依然


问题:

String s1 = new String(“hello world”); String s2 = “hello world” 比较区别?

答:

前者创建了两个对象 后者只创建了一个对象,对于后者下次在创建同样的内容(以同样的方法)不会再在内存中生成新的

String str = “hello”;

str是一个引用,指向了常量池中的”hello”这个对象。

对于new String(“…”)

在堆中new出来的这个对象自己有一个成员char []value来指向这个在常量池中字符串的。

s1==s2 //返回flase 因为对于引用类型 比较的是地址值

s1.equals(s2) //返回 true 因为 String重写了equals方法 所以只比较值而不比较地址

内存图解:



[code]String s1 = "hello";
String s2 = "hello";
s1==s2; //true 他们的地址是一样的
String s3 = new String("hello world");
String s4 = new String("hello world");
s3==s4 // false 他们的地址是不一样的
String s5 = "hello";
String s6 = "word";
String s7="helloword";
s7.equals(s5+s6);//true
//如果是字符串变量相加,先开空间。再相加存储
s7==s5+s6;//false
//如果是常量相加,先加,然后在常量池中寻找,如果有就返回常量池的地址,否则创建新的空间。
s7="hello"+"word";//false


String的一个面试题:

为什么说String类型的参数传递。形参的改变不会影响实参内容?

因为String是一个不可变类型,也就是说从声明那一刻起内存大小是固定的不可改变的,但StringBuffer可以

String str = “java”+“is”+“my”+“life”; 这句话只创建了一个字符串对象。因为str的值在编译的时候可以确定下来(那些值都是常量)

字符串的查找功能

[code]* int length():获取字符串的长度 
* char charAt(int index):获取字符串中指定索引处的字符 
* int indexOf(int ch):获取ch这个字符在该字符串中第一次出现的索引。 
* int indexOf(String str):获取str这个字符串在该字符串中第一次出现的索引。 
* int indexOf(int ch,int fromIndex):获取ch这个字符在该字符串中从指定索引开始后的第一次出现的索引。 
* int indexOf(String str,int fromIndex):获取str这个字符串在该字符串中从指定索引开始后的第一次出现的索引。 
* String substring(int start):获取子串。截取。从start到末尾。 
* String substring(int start,int end):获取子串。截取。从start到end。






使用字符串时的优化:StringBuffer与StringBuilder

很多资料都说优先使用StringBuffer,那是因为这些资料都是jdk1.5之前的——过时了。

实际上我们应该优先使用StringBuilder。

StringBuffer与StringBuilder唯一的区别在于StringBuffer是线程安全的,会减低效率,没有多线程的时候优先使用StringBuilder.

问题:

String ,StringBuilder,StringBuffer如何区别?

String 字符串长度固定。

StringBuilder/StringBuffer长度可变。

StringBuilder线程不安全,效率高

StringBuffer线程安全,效率低

StringBuffer: (注意两个方法 length() 和 capacity());

通过调用length()方法可以得到当前StringBuffer的长度。而通过调用capacity()方法可以得到总的分配容量

它们的一般形式如下:

int length()

int capacity()

示例:

class StringBufferDemo

{

public static void main(String args[])

{

StringBuffer sb = new StringBuffer(“Hello”);

System.out.println(“buffer = “+sb);

System.out.println(“length = “+sb.length);

System.out.println(“capacity = “+sb.capacity);

}

}

下面是这个程序的输出,它说明了StringBuffer如何为另外的处理预留额外的空间:

buffer = Hello

length = 5

capacity = 21

由于sb在创建时由字符串”Hello”初始化,因此它的长度为5。因为给16个附加的字符自动增加了存储空间,因此它的存储容量为21.

[code]构造方法:
StringBuffer();  
StringBuffer(int capacity);
StringBuffer(String str);


常用方法:

[code]增加字符(如何类型):
append(Object obj);    //任意字符都可以
从中添加字符
insert(int offset,Object obj);
删除功能:
delect(int start,int end);      //删除从start到end的数据
delectCharAt(int index);    //删除index位置的数据
替换功能:
replace(int start,int end,String str);


上述方法的返回值都是StringBuffer的

[code]public String substring(int start);
public String substring(int start, int end);   返回值是String
StringBuffer使用substring两个方法后,本身不变,返回一个String类型
例:
StringBuffer  sb = new StringBuffer("hello world");
sb.substring(5);
System.out.println(sb);    //打印依然为hello world
String s = sb.substring(5);
System.out.println(s);     //打印依然为world
StringBuffer的反转功能:
public StringBuffer reverse();


StringBuffer与String的相互转化:

[code]A : String->StringBuffer
方法1:
String  s = "hello world";
StringBuffer sb = new StringBuffer(s);
方法2:
String  s = "hello world";
StringBuffer sb = new StringBuffer();
sb.append(s);
A : StringBuffer->String
方法1.
StringBuffersb = new StringBuffer("hello world");
String s = new String(sb);
方法2.
StringBuffersb = new StringBuffer("hello world");
String s = sb.toString();


equals与==的区别:

int i=10;

int j=10;

此时 i==j;//true

String a = new String(“abc”);

String b = new String(“abc”);

此时a==b;//false

对象变量其实是一个引用,它们的值是指向对象所在的内存地址,a和b字符串使用了”new”所以在内存中有两个内容为”abc”的字符串。既然是两个,它们自然内存地址不一样。a和b的值其实是两个不同内存地址的值,所以使用”==”结果为false。然而,它们的内容都是”abc”。应该是“相等”的,但是 “==” 操作符并不设计对象内容的比较,因为那是equals的事。。我们看看Object对象equals方法是如何实现的:

[code]boolean equals(Object o){
  return this==0;
}


Object类默认使用了”==”操作符。所以如果你的类没有重写equals方法的话和使用”==”得到同样的结果。所以以后在判断变量是否相等时,不要想当然来操作,因为这个由类的创建者来决定。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: