String 类的常用方法都有那些
- indexOf():返回指定字符的索引。
- charAt():返回指定索引处的字符。
- replace():字符串替换。
- trim():去除字符串两端空白。
- split():分割字符串,返回一个分割后的字符串数组。
- getBytes():返回字符串的 byte 类型数组。
- length():返回字符串长度。
- toLowerCase():将字符串转成小写字母。
- toUpperCase():将字符串转成大写字符。
- substring():截取字符串。
- equals():字符串比较。
【1】字符串截取与分割
测试代码如下:
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import org.junit.Test;
public class TestStringToken {
public void subSting() {
String str = "java,javac,javae";
String s1 = str.substring(2);//"va,javac,javae"
String s2 = str.substring(0,2);//"ja"
System.out.println(s1);
System.out.println(s2);
}
//substring准则为左闭右开
public void stringTokenizer() {
String str = "java,javac,javae";
StringTokenizer stringTokenizer = new StringTokenizer(str, ",");
// while (stringTokenizer.hasMoreElements()) {
// Object object = (Object) stringTokenizer.nextElement();
// System.out.println(String.valueOf(object));
//
// }
while (stringTokenizer.hasMoreTokens()) {
System.out.println(stringTokenizer.nextToken());
}
}
// 根据标识分割字符串
public void split() {
String str = "java,javac,javae";
String[] s = str.split(",");
for (String string : s) {
System.out.println(string);
}
}
//使用正则表达式
public void pattern() {
String str = "java,javac,javae";
Pattern p = Pattern.compile(",");
String[] s = p.split(str);
for (String string : s) {
System.out.println(string);
}
}
}
【2】char与String转换
Java中char是一个基本类型,而String是一个引用类型。有时候我们需要在它们之间互相转换。
String转换为char
① 使用String.charAt(index)(返回值为char)可以得到String中某一指定位置的char。
② 使用String.toCharArray()(返回值为char[])可以得到将包含整个String的char数组。这样我们就能够使用从0开始的位置索引来访问string中的任意位置的元素。
char转换为String
将char转换为String大致有6种方法。总结如下:
1. String s = String.valueOf('c'); //效率最高的方法
2. String s = String.valueOf(new char[]{'c'}); //将一个char数组转换成String
3. String s = Character.toString('c');
// Character.toString(char)方法实际上直接返回String.valueOf(char)
4. String s = new Character('c').toString();
5. String s = "" + 'c';
// 虽然这个方法很简单,但这是效率最低的方法
// Java中的String Object的值实际上是不可变的,是一个final的变量。
// 所以我们每次对String做出任何改变,都是初始化了一个全新的String Object并将原来的变量指向了这个新String。
// 而Java对使用+运算符处理String相加进行了方法重载。
// 字符串直接相加连接实际上调用了如下方法:
// new StringBuilder().append("").append('c').toString();
6. String s = new String(new char[]{'c'});
【3】String中的substring ()方法是怎样工作的?
子字符串通过获取原始字符串的一部分,从原 string 对象中创建一个新对象。需要注意的是子字符串会造成的内存泄漏风险。
jdk1.6下:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
substring后,返回的新字符串会和旧字符串共享内部的value(char数组),这样看似合理共享利用的内存,但可能会带来一些问题:如果程序从外部读到了一个大字符串,然后只需要大字符串的一部分,做了substring,但实际上还是会hold住整个大字符串的内容在内存里面。如果这样的情况很多,就可能会出现问题。
直到Java 1.7, 子字符串保持着原始字符数组引用,这意味着即使5个字符长的子字符串也能阻止1GB的字符数组被垃圾回收器回收,因为子字符串保持着它的一个强引用。
在jdk1.7后,String类做了调整,去掉了offset和count域,substring也做了调整,看下源码:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}
原始字符数组不再被引用,但这个改变也造成创建子字符串要花费多一点时间。之前,它在 O(1) 复杂度内完成,在 Java7 中最坏情况下,它会达到 O(N) 复杂度。
【3】String.format
如格式化为3三位,不足就前置补0:
String format = String.format("%03d", 3);