字符串

Java没有内置字符串类型,标准Java类库里有预定义类String。

1.子串

String.substring(beginIndex, endIndex) 开闭区间

String greeting = "Hello";
String s = greeting.substring(0,3);//s="Hel"

2.拼接

用+

int age = 13;
String s = "PG" + age;
//s = PG13

3.不可变字符串

Java中的字符串内容是不可变的。
修改字符串的方法:提取需要的字符,拼接替换的字符串。

greeting = greeting.substring(0,3) + "p!";  //greeting从"Hello"变为"Help!"

字符串拼接效率虽然较低,但实现了字符串可共享。低效率远远被共享带来的高效率抵消。(关于共享的概念,似乎在栈内存或堆内存中,以后看到了再回来补充)
不可变:创建完成后状态不能改变。

在Java中,不能直接操作对象本身,通过引用才能访问对象。s、greeting都是引用。

字符串greeting的内容不能改变:字符串“hello”内容已经生成在内存区中,不能再改变。若用如下方法可以改变字符串的引用对象,但无法改变内存区中的内容。

//使字符串对象的引用s指向另一个字符串对象,但"123"仍然存在
String s = "123";
s = "abc";

原始字符串放置在堆内存中,如果将greeting赋予另外一个值,则此块内存不再使用,Java将自动进行内存回收(垃圾回收)。

4.检测字符串是否相等

//字符串s与t是否相等
s.equals(t);
"Hello".equals(greeting);
//若不想区分大小写
"Hello".equalsIgnoreCase("hello");

** 不能用 == 检测两字符串是否相等,==只能确定两字符串是否放在同一位置。
如果是字符串共享可以用==判断,但实际只有字符串常量能共享。

5.代码点与代码单元

代码点:一个编码表中的某个字符对应的代码值,也就是Unicode编码表中每个字符对应的数值。

代码单元:在UTF-16中的基本多语言级别中,每一个字符用16位表示,通常被称为代码单元。因为UTF-16编码采用不同长度的编码表示所有的Unicode代码点,因此增补字符采用的是一对连续的代码单元进行编码。

字符串由char序列构成。char是表示Unicode代码点的代码单元。
s.length():UTF-16编码表示下的字符串的代码单元数量,而非字符个数。返回的是字符串长度。
s.codePointCount(0,s.length()):表示代码点数量,实际的长度。
s.charAt(n):返回指定位置n的代码单元,而非我们所认为的字符。0~s.length()-1

char first = greeting.charAt(0);//first:H
char last = greeting.charAt(4);//last:o

想得到第i个代码点

int index = greeting.offsetByCodePoints(0,i);//0:起始位置,i:代码单元数量。返回代码点索引
int cp = greeting.codePointAt(index);

遍历一个字符串,依次查看每个代码点:

int cp = sentence.codePointAt(i);
if(Character.isSupplementaryCodePoint(cp)) i += 2;//isSupplementaryCodePoint:判断指定字符(Unicode代码点)是否在增补字符范围内,返回boolean
else i++;

//回退操作
i--;
if(Character.isSupplementaryCodePoint(cp)) i--;


6.字符串API

• char charAt (int index)
返回给定位置的代码单元。除非对底层的代码单元感兴趣,否则不需要调用这个方法。
• int codePointAt(int index) 5.0
返回从给定位置开始或结束的代码点。
• int offsetByCodePoints(int startIndex, int cpCount) 5.0
返回从startIndex代码点开始,位移cpCount后的代码点索引。
• int compareTo(String other)
按照字典顺序,如果字符串位于other之前,返回一个负数;如果字符串位于other之后,
返回一个正数;如果两个字符串相等,返回0。
• boolean endsWith(String suffix)
如果字符串以suffix结尾,返回true。
• boolean equals(Object other)
如果字符串与other相等,返回true。
• boolean equalsIgnoreCase(String other)
如果字符串与other相等(忽略大小写),返回true。
• int index0f(String str)
• int index0f(String str, int fromIndex)
• int index0f(int cp)
• int index0f(int cp, int fromIndex)
返回与字符串str或代码点cp匹配的的第一个子串的开始位置。这个位置从索引0或
fromIndex开始计算。如果在原始串中不存在str,返回-1。
• int lastIndex0f(String str)
• int lastIndex0f(String str, int fromIndex)
• int lastindex0f(int cp)
• int lastindex0f(int cp, int fromIndex)
返回与字符串str或代码点cp匹配的最后一个子串的开始位置。这个位置从原始串尾端或
fromIndex开始计算。
• int length( )
返回字符串的长度。
• int codePointCount(int startIndex, int endIndex) 5.0
返回startIndex和endIndex-1之间的代码点数量。没有配成对的代用字符将计入代码点。
• String replace(CharSequence oldString,CharSequence newString)
返回一个新字符串。这个字符串用newString代替原始字符串中所有的oldString。可以用
String或StringBuilder对象作为CharSequence参数。
• boolean startsWith(String prefix)
如果字符串以preffix字符串开始,返回true。
• String substring(int beginIndex)
• String substring(int beginIndex, int endIndex)
返回一个新字符串。这个字符串包含原始字符串中从beginIndex到串尾或endIndex-1的所
有代码单元。
• String toLowerCase( )
返回一个新字符串。这个字符串将原始字符串中的所有大写字母改成了小写字母。
• String toUpperCase( )
返回一个新字符串。这个字符串将原始字符串中的所有小写字母改成了大写字母。
• String trim( )
返回一个新字符串。这个字符串将删除了原始字符串头部和尾部的空格。

7.构建字符串

StringBuilder类:用许多小段字符串构建一个字符串。

StringBuilder builder = new StringBuilder();
builder.append(ch);//添加字符
builder.append(str);//添加字符串
String completedString = builder.toString();//得到String对象

• StringBuilder()
构造一个空的字符串构建器。
• int length()
返回构建器或缓冲器中的代码单元数量。
• StringBuilder append(String str)
追加一个字符串并返回this。
• StringBuilder append(char c)
追加一个代码单元并返回this。
• StringBuilder appendCodePoint(int cp)
追加一个代码点,并将其转换为一个或两个代码单元并返回this。
• void setCharAt(int i,char c)
将第i个代码单元设置为c。
• StringBuilder insert(int offset,String str)
在offset位置插入一个字符串并返回this。
• StringBuilder insert(int offset,Char c)
在offset位置插入一个代码单元并返回this。
• StringBuilder delete(int startIndex,int endIndex)
删除偏移量从startIndex到-endIndex-1的代码单元并返回this。
• String toString()
返回一个与构建器或缓冲器内容相同的字符串。