目录
1.3.2 boolean equals(Object anObject)方法比较引用对象的内容是否一致
1.3.3 int compareTo(String s)方法:
1.3.4 int compareToIgnoreCase(String str) 忽视大小写比较:
3. StringBuilder 和StringBuffer
1. String类的常用方法
1.1 字符串构造
String提供了很多构造方法,以下三种常用:
//使用常量串进行构造
String str1 = "hello";
System.out.println(str1);
//new String对象
String str2 = new String("hello");
System.out.println(str2);
//使用字符数组进行构造
char[] array = {'h','e','l','l','o'};
String str3 = new String(array);
System.out.println(str3);
注:1、String是引用类型,内部并不存储字符串本身:
双击Shift搜索String类查看文件:
或debug进行调试:
以str1为例,实际内存分布如下:
1.2 字符串常用方法
1.2.1 length()方法:
String str = "hello world";
System.out.println(str.length());
输出结果为:
注意:(1)字符串与数组的区别:
char[] array = {'h','e','l','l','o',' ','w','o','r','l','d'};
System.out.println(array.length);
数组的length可以视为一种属性,不同于String类的方法;
(2)在java中" "引起来的也是String类的对象:
String str = "hello world";
System.out.println(str.length());
System.out.println("hello world".length());
输出结果为:
1.2.2 isEmpty()方法:
String str = "hello world";
System.out.println(str.isEmpty());
String str2 = "";
System.out.println(str2.isEmpty());
输出结果为:
注意以下两个语句的区别:
String str2 = "";
代表str2指向的对象中没有存储字符;
String str3 = null;
代表str3不指向任何对象,故而不可以调用String类的方法,否则会抛出空指针异常;
1.3 String对象的比较
字符串的比较会应用在字符串排序等等场合中,java中共提供了四种方式:
1.3.1 == 比较是否引用同一个对象
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2);
String str3 = str1;
System.out.println(str1 == str3);
输出结果为:
1.3.2 boolean equals(Object anObject)方法比较引用对象的内容是否一致
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
输出结果为:
注:String类重写了其父类Object类的equals方法;
1.3.3 int compareTo(String s)方法:
String str1 = new String("abcde");
String str2 = new String("abfcd");
//f在c之后,str2>str1
String str3 = new String("abcde");
System.out.println(str1.compareTo(str2));
System.out.println(str2.compareTo(str1));
System.out.println(str1.compareTo(str3));
输出结果为:
调用compareTo()方法的字符串对象比传递给compareTo()方法的字符串对象小时返回一个负数,大时返回一个正数,相等时返回0;
注:(1)当两个字符串长度不相同而使用compareTo方法进行比较时:
String str4 = new String("abcdefg");
String str5 = new String("abcd");
System.out.println(str4.compareTo(str5));
输出结果为:
(2)compareTo()方法的返回值:
1.3.4 int compareToIgnoreCase(String str) 忽视大小写比较:
String str6 = new String("hello");
String str7 = new String("Hello");
System.out.println(str6.compareTo(str7));
System.out.println(str6.compareToIgnoreCase(str7));
输出结果为:
1.4 字符串查找
1.4.1 char charAt(int index):
String str1 = "hello world";
for(int i=0;i<str1.length();i++){
System.out.print(str1.charAt(i)+" ");
}
输出结果为:
1.4.2 int indexOf():
String str2 = "ababcababccc";
//默认从起始位置开始查找第一个字符c
System.out.println(str2.indexOf('c'));
//从下标7开始查找第一个字符c
System.out.println(str2.indexOf('c',7));
//待查找的字符在字符串中不存在
System.out.println(str2.indexOf('d'));
//查找子字符串第一次出现的位置(返回第一个字符的下标)
System.out.println(str2.indexOf("babcc"));
输出结果为:
1.4.3 int lastIndexOf():
String str3 = "ababcababccc";
System.out.println(str3.lastIndexOf('b'));
System.out.println(str3.lastIndexOf("ab"));
System.out.println(str3.lastIndexOf('b',5));
输出结果为:
1.5 转换
1.5.1 数值和字符串转换
//数字转字符串
String str = String.valueOf(123);
String str1 = str+"456";
System.out.println(str1);
//字符串转数字
//1.转整型
String str2 = "1234";
System.out.println(data1);
//2.转浮点型
String str3 = "123.456";
double data2 = Double.parseDouble(str3)+111.111;
System.out.println(data2);
输出结果为:
1.5.2 大小写转换
String str1 = "hello WORLD";
String str2 = "HELLO world";
//小写转大写
System.out.println(str1.toUpperCase());
//大写转小写
System.out.println(str2.toLowerCase());
输出结果为:
1.5.3 字符串转数组
String str1 = "hello";
char[] array = str1.toCharArray();
for(char x:array){
System.out.print(x+" ");
}
System.out.println();
输出结果为:
1.5.4 格式化
String str1 = String.format("%d - %d - %d",1997,8,5);
System.out.println(str1);
输出结果为:
1.6 字符串替换
字符串替换:使用一个指定的新的字符换替换掉已有的字符串数据:
String str1 = "ababcde";
String ret1 = str1.replace('b','x');
System.out.println(ret1);
String ret2 = str1.replace("ab","xyz");
System.out.println(ret2);
String ret3 = str1.replaceAll("ab","mn");
System.out.println(ret3);
String ret4 = str1.replaceFirst("ab","99");
System.out.println(ret4);
输出结果为:
注:字符串是不可变对象,替换不是修改当前字符串,而是产生一个新的字符串;
1.7 字符串的拆分
1.7.1 字符串的全分割
String str1 = "hello world HELLO JAVA";
String[] tmp = str1.split(" ");
for(String s:tmp){
System.out.println(s);
}
输出结果为:
1.7.2 字符串的部分分割
public static void main(String[] args) {
String str1 = "hello world HELLO JAVA";
String[] tmp = str1.split(" ",2);
for(String s:tmp){
System.out.println(s);
}
}
输出结果为:
1.7.3 需要转义字符帮助的字符串分割
String str2 = "1997.08.05.0.1";
String[] tmp2 = str2.split(".");
for(String s:tmp2){
System.out.println(s);
}
实际并未输出:
注:在使用"|"、"*"、"+"等都得加上转义字符"\\"才能作为分隔符,如果是"\"就需要写成"\\\\" :
String str2 = "1997.08.05.0.1";
String[] tmp2 = str2.split("\\.");
for(String s:tmp2){
System.out.println(s);
}
输出结果为:
1.7.4 字符串的多分隔符分割
String str3 = "1997.8-05&2014.9-15";
String[] tmp3 = str3.split("\\.|-|&");
for(String s:tmp3){
System.out.println(s);
}
输出结果为:
1.7.5 字符串的多次分割
String str = "name=Mike&age=20";
String[] tmp1 = str.split("&");
for(String s1:tmp1){
String[] tmp2 = s1.split("=");
for(String s2:tmp2){
System.out.println(s2);
}
}
输出结果为:
1.8 字符串截取
截取字符串:从一个完整的字符串中截取出部分内容;
String str = "hello world HELLO JAVA";
String ret1 = str.substring(12);
System.out.println(ret1);
String ret2 = str.substring(6,18);
System.out.println(ret2);
输出结果为:
注意起始和终止位置的下标是左闭右开的;
1.9 其他操作方法
操作字符串的常用方法还有:去掉字符串首尾空格、保留其他空格的trim方法:
String str = " hello world HELLO JAVA ";
System.out.println(str);
String ret = str.trim();
System.out.println(ret);
输出结果为:
2.字符串的不可变性与修改
2.1 字符串的不可变性
String是一种不可变对象,字符串中的内容是不可改变的;
双引号引用的常量都会被存储到堆中的常量池中,虚拟机栈中的变量存储的是常量池中常量的地址,常量池是不可改变的;
试运行以下代码:
String str1 = "abcd";
String str2 = new String("abcd");
System.out.println(str1 == str2);
String str3 = "abcd";
System.out.println(str1 == str3);
输出结果为:
内存分布如下:
实际上java官方并未提供常量池的概念,常量池的底层是一个C++哈希表;
2.2 字符串的修改
(1)final修饰类表示类不能被继承,final修饰引用类型表示该引用变量不能引用其他对象,但是其引用对象中的内容是可修改的:
(2)为什么String类要设计为不可变?
① 方便实现字符串对象池,如果String类可变,那么对象池就需要考虑写时拷贝的问题;
② 不可变对象是线程安全的;
③ 不可变对象更方便缓存hash code,作为key时可以更高效地保存到HashMap中;
(3)尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新的临时变量,效率非常低下,如:
String str = "hello";
str += " world";
System.out.println(str);
等效于:
String str = "hello";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(str);
stringBuilder.append(" world");
str = stringBuilder.toString();
System.out.println(str);
3. StringBuilder 和StringBuffer
3.1 StringBuilder
StringBuilder stringBuilder1 = new StringBuilder();
StringBuilder stringBuilder2 = new StringBuilder("abc");
System.out.println(stringBuilder2);
stringBuilder2.append(19.9);
stringBuilder2.append("def");
System.out.println(stringBuilder2);
输出结果为:
注:(1)String与StringBuilder最大的区别在于String的内容无法修改而StringBuilder的内容可以修改,频繁修改字符串的情况下可以考虑使用StringBuilder;
(2)String转换为StringBuilder:利用StringBuilder的构造方法或append90方法;
StringBuffer转换为String:调用toString()方法;
3.2 StringBuffer
StringBuffer的用法与StringBuilder的方法使用基本类似,以append方法为例展示区别:
注:试分析:
String str1 = new String("ab");
//创建了2个String对象
String str2 = new String("a")+new String("b");
//创建了5个String对象和1个StringBuilder对象