Java之美从菜鸟到高手演变之字符串的处理Word下载.docx
《Java之美从菜鸟到高手演变之字符串的处理Word下载.docx》由会员分享,可在线阅读,更多相关《Java之美从菜鸟到高手演变之字符串的处理Word下载.docx(25页珍藏版)》请在冰豆网上搜索。
s2
8.
System.out.println(s
==
s2);
9.
}
10.}
该程序输出:
true因为s和s2都指向了helloworld字符串,他们的地址是同一个。
我们常说,String的一个很大的特点,就是它是一个“不可变的字符串”,就是说,当一个String对象完成创建后,该对象的内容就固定下来了,但是为什么还会有下面这种情况呢?
StringInit
str
I
like"
//---------1--------
System.out.println(System.identityHashCode(str));
+
java"
//--------2---------
10.
11.}
14576877
12677476
说明:
str似乎是变了,这是为什么呢?
其实是这样的:
str只是一个引用变量,当程序执行完1后,str指向“Ilike”。
当程序执行完2之后,连接运算符会将两个字符串连在一起,并且让str指向新的串:
Ilikejava"
,所以,从这里应该可以看得出来,最初的对象确实没有改变,只是str所指向的对象在不断改变。
String对象的另一种初始化方式,就是采用String类提供的构造方法进行初始化。
String类提供了16种构造方法,常用的有五种:
String()---------
初始化一个String对象,表示一个空字符序列
String(Stringvalue)
---------
利用一个直接量创建一个新串
String(char[]value)
利用一个字符数组创建
String(char[]value,intoffset,intcount)
截取字符数组,从offset开始count个字符创建
String(StringBufferbuffer)
利用StringBuffer创建
形如:
Strings=newString();
Strings1=newString(“hello”);
char[]c={'
h'
'
e'
l'
o'
};
Strings2=newString(c);
'
Strings3=newString(c,1,3);
以上就是String类的基本初始化方法。
2、String类的一些常用方法
字符串是最常用的对象,所以,我们有必要彻底的了解下它,下面我会列举常用的字符串里的方法,因为有很多,就不一一列举。
-------publicintlength()--------
该方法用于获取字符串的长度,实现如下:
1./**
*
Returns
the
length
of
this
string.
3.
The
is
equal
to
number
<
a
href="
Character.html#unicode"
>
Unicode
code
units<
/a>
in
@return
sequence
characters
represented
by
object.
*/
int
length()
return
count;
11.
这是JDK种的原始实现,count在String类里被定义为一个整型常量:
privatefinalintcount;
并且不论采用哪种构造方法,最终都会为count赋值。
使用方法:
1.String
2.int
s.length();
这个比较简单。
-----------publicbooleanequals(ObjectanObject)-----------
该方法用于比较给定对象是否与String相等。
JDK里是这样实现的:
Compares
string
specified
result
{@code
true}
if
and
only
argument
not
null}
String}
object
that
represents
same
as
@param
anObject
compare
against
given
equivalent
string,
false}
otherwise
12.
13.
@see
#compareTo(String)
14.
#equalsIgnoreCase(String)
15.
16.
boolean
equals(Object
anObject)
17.
(this
18.
true;
19.
20.
(anObject
instanceof
String)
21.
anotherString
(String)anObject;
22.
n
23.
(n
anotherString.count)
24.
char
v1[]
value;
//---------1---------
25.
v2[]
anotherString.value;
//-------2----------
26.
i
offset;
27.
j
anotherString.offset;
28.
while
(n--
!
0)
29.
(v1[i++]
v2[j++])
30.
false;
31.
32.
33.
34.
35.
36.
从1和2处也看出来,String的底层是基于字符数组的。
我们可以像下面这种方式使用equals():
s1
new
String("
);
2.String
3.String
s3
hello"
4.System.out.println(s1.equals(s2));
5.System.out.println(s1.equals(s3));
结果输出:
true
false
此处插入一个很重要的知识点,重写equals()的一般步骤及注意事项:
1.使用==操作符检查“实参是否为指向对象的一个引用”。
2.使用instanceof操作符检查“实参是否为正确的类型”。
3.把实参转换到正确的类型。
4.对于该类中每一个“关键”域,检查实参中的域与当前对象中对应的域值是否匹配。
a.对于既不是float也不是double类型的基本类型的域,可以使用==操作符进行比较
b.对于对象引用类型的域,可以递归地调用所引用的对象的equals方法
c.对于float类型的域,先使用Float.floatToIntBits转换成int类型的值,然后使用==操作符比较int类型的值
d.对于double类型的域,先使用Double.doubleToLongBits转换成long类型的值,然后使用==操作符比较long类型的值。
5.当你编写完成了equals方法之后,应该问自己三个问题:
它是否是对称的、传递的、一致的?
(其他两个特性通常会自行满足)
如果答案是否定的,那么请找到这些特性未能满足的原因,再修改equals方法的代码。
稍后我再做说明,请先再看个例子:
3./**
字符串比较:
equals()和==的区别
@author
二青
8.public
s4
System.out.println(s.equals(s1));
System.out.println(s1.equals(s2));
System.out.println(s1.equals(s3));
System.out.println("
------------------"
s1);
s3);
s4);
26.}
输出:
------------------
此处验证了一个问题,就是比较方法equals()和==的区别,一句话:
equals()比较的是对象的内容,也就是JVM堆内存中的内容,==比较的是地址,也就是栈内存中的内容。
如上述代码中,s、s1、s2、s4他们四个String对象的内容都是"
,所以,用equals()比较他们,返回的都是true。
但是,当s和s1用==比较时,却返回false,因为二者在堆中开辟的地址不一样,所以,返回的肯定是false。
而为什么s和s4用==比较时,返回的是true呢,因为上文中提到过,直接量的字符串会产生缓存池,所以,当声明s4的时候,编译器检测到缓存池中存在相同的字符串,所以就直接使用,只要将s4指向s所指向的字符串就行了,二者指向同一字符串,所以地址当然相等!
注意:
此处隐藏着一个比较细的编程习惯,尤其是用==进行比较的时候,尽量将常量放在==的左边,因为我们有的时候,会不小心将==写成=,这样的话,如果将常量放在左边,编译器会报错,提醒你,但是,如果将变量放在左边,常量放右边,即使你写成了=,编译器默认为变量赋值了,因此也不会报错。
因为String类实现了publicinterfaceComparable<
T>
,而Comparable接口里有唯一的方法:
publicintcompareTo(To)。
所以,String类还有另一个字符串比较方法:
compareTo()
-----------------publicintcompareTo(StringanotherString)---------------
compareTo()可实现比较两个字符串的大小,源码如下:
1.public
compareTo(String
anotherString)
len1
len2
anotherString.count;
Math.min(len1,
len2);
(i
j)
k
i;
lim
(k
lim)
c1
v1[k];
c2
v2[k];
(c1
c2)
-
c2;
k++;
else
v1[i++];
v2[j++];
len2;
compareTo是怎么实现的呢?
首先,会对两个字符串左对齐,然后从左到右一次比较,如果相同,继续,如果不同,则计算不同的两个字符的ASCII值的差,返回就行了。
与后面的其他字符没关系。
举个例子:
compareTo()测试
CompareToTest
hallo"
ha"
haeeo"
pareTo(s2);
a:
+a);
b
pareTo(s3);
b:
+b);
c
c:
+c);
21.}
程序输出:
3
7
-3
s和s2相比,前两个相同,如果是这种情况,则直接返回length1-length2
s和s3相比,前两个相同,不用管,直接用第三个字符的ASCII码做差就行了。
所以'
-'
a'
=7
此处网友“handsomeman_wei”问我源码中的c1-c2理解不了,就是上面红字部分的解释。
s2和s3相比,同第一种情况一样,只是length1比length2小,因此值为负数。
-----------publiccharcharAt(intindex)-----------
获取指定位置的字符,比较容易理解,源码为:
charAt(int
index)
((index
||
(index
count))
throw
StringIndexOutOfBoundsException(index);
value[index
offset];
chara=s.charAt
(2);
System.out.println(a);
l
参数index的值从0到字符串的长度-1,所以,如果值不在这个范围内,如下:
chara=s.charAt(8);
则报错:
Exceptioninthread"
main"
java.lang.StringIndexOutOfBoundsException:
Stringindexoutofrange:
8
atjava.lang.String.charAt(String.java:
686)
atcom.xtfggef.string.CompareToTest.main(CompareToTest.java:
20)
与charAt()相对应的是indexOf():
根据给定的字符串,返回他的位置。
indexOf()有多个参数:
publicintindexOf(intch)
publicintindexOf(intch,intfromIndex)
publicintindexOf(Stringstr)
publicintindexOf(Stringstr,intfromIndex)
staticintindexOf(char[]source,intsourceOffset,intsourceCount,
char[]target,inttargetOffset,inttargetCount,
intfromIndex)
有兴趣的自己去试试,这儿就不多阐述了。
-----------substring()------------
substring(int
beginIndex)
substring(beginIndex,
count);
用于截取字符串,此处与另一个方法对比:
beginIndex,
endIndex)
(beginIndex
StringIndexOutOfBoundsException(beginIndex);
(e