java String类
1.String类
- 字符串是常量,创建后不可改变
- 字符串字面值存储在字符串池(方法区)中,可以共享(JDK1.8后方法区合并到堆中)
- 直接将字面值赋值时,会在常量池中创建对象,并将此变量指向常量池中的字面值对象
- 通过new来创建String类型的对象时,会创建两个对象,一个在堆中,一个在常量池中,栈中的String类型变量存放堆中对象的地址,堆中对象则指向常量池中的对象
public class StringDemo {
public static void main(String[] args) {
String name="hello";// "hello"常量的字面值存放在字符串池中
System.out.println(name.hashCode());//输出103061
name="zhangsan";//"zhangsan"赋值给name1,并没有修改数据,而是重新在常量池中开辟了一块新的空间,此时"hello"就成为垃圾
System.out.println(name.hashCode());//输出3536149
String name2="zhangsan";
System.out.println(name2.hashCode());//输出3536149
System.out.println(name==name2);//true
//字符串的另一种创建方式new
String str=new String("java");
String str2=new String("java");
System.out.println(str.hashCode());//输出3254818
System.out.println(str2.hashCode());//输出3254818
System.out.println(str==str2);//false栈中的值不一样
System.out.println(str.equals(str2));//true
}
}
2.String类的常用方法
- length():返回字符串的长度
- charAt(int index):返回索引处的字符
- contains(String str):判断是否包含子字符串str,返回的是boolean类型
public static void main(String[] args) {
String str="hello, 宋平";
System.out.println(str.length());//9,空格也算是一个字符
System.out.println(str.charAt(0));//h
System.out.println(str.charAt(str.length()-1));//平
//System.out.println(str.charAt(str.length()));//报错,string越界
System.out.println(str.contains(" "));//true
System.out.println(str.contains(","));//true
System.out.println(str.contains(", "));//true
System.out.println(str.contains("hello"));//true
System.out.println(str.contains("he llo"));//false
}
- toCharArray():将字符串转换成数组
- indexOf(String str):查找str首次出现的下标,存在则返回该下标,不存在返回-1
- lastIndexOf(String str):查找str最后一次出现的下标,存在则返回该下标,不存在返回-1
public class StringDemo03 {
public static void main(String[] args) {
String str="hello,宋小平,hello,韩信,hello";
//输出[h, e, l, l, o, ,, 宋, 小, 平, ,, h, e, l, l, o, ,, 韩, 信, ,, h, e, l, l, o]
System.out.println(Arrays.toString(str.toCharArray()));
System.out.println(str.indexOf("hello"));//0
System.out.println(str.indexOf("hello",1));//10
System.out.println(str.lastIndexOf("hello"));//19
}
}
- trim():去掉字符串前后的空格
- toUpperCase():将小写转换为大写
- endsWith(String str):判断字符串是不是以str结尾
public class StringDemo04 {
public static void main(String[] args) {
String str=" Hello Java ";
System.out.println(str.trim());//Hello Java
System.out.println(str.toUpperCase());// HELLO JAVA
System.out.println(str.toLowerCase());// hello java
String fileName="hello.java";
System.out.println(fileName.startsWith("he"));//true
System.out.println(fileName.endsWith(".java"));//true
}
}
- replace(char oldChar,char newChar):将旧字符串替换为新字符串
- split(String str):对字符串做拆分
- equals和compareTo:compareTo是比较的字符串的大小(字典表中的位置:前一个减去后一个),如果两个字符串的第一个字符相等,则用其后面的进行比较,如果其中一个字符串是从第一位开始和另一个字符串皆相等,但长度不同,返回的结果为第一个字符串的长度减去第二个字符串的长度
- equalsIgnoreCase(String str):忽略大小写比较
public class StringDemo05 {
public static void main(String[] args) {
String str="hello,宋小平,hello,韩信,hello";
//你好,宋小平,你好,韩信,你好
System.out.println(str.replace("hello", "你好"));
String[] st=str.split(",");
for (String a: st) {
System.out.println(a);
}
System.out.println("--------补充----------");
String s1="hello";
String s2="HELLO";
System.out.println(s1.equalsIgnoreCase(s2));//true忽略大小写比较
String s3="abc";//a在ASSIC码中的编码位置为97
String s4="xyz";//x在ASSIC码中的编码位置为120
System.out.println(s3.compareTo(s4));//返回97-120=-23
//第一位都是a,则比较下一位
String s5="abc";//b在ASSIC码中的编码位置为98
String s6="ayz";//y在ASSIC码中的编码位置为121
System.out.println(s3.compareTo(s4));//返回98-121=-23
//下面这种情况,则用长度来进行比较
String s7="abc";//前三位这s8的一样,则用长度来比较,长度为3
String s8="abcdef";//长度为6
System.out.println(s7.compareTo(s8));//返回3-6=-3
}
}
3.StringBuffer和StringBuilder
因为String的不可变性,在操作过程中可能会出现无用的垃圾;同时 ,每次操作的时候都会产生一个新的字符串,效率相对低。
针对以上问题,sun公司开发出StringBuffer类(JDK1.0提供),是String的增强类,可变长字符串,相对于StringBuilder来说 ,运行效率低,线程安全。
StringBuilder可变长字符串,jdk1.5提供,运行效率比StringBuffer高,线程不安全,单线程首选。
StringBuffer
/*
* StringBuffer and StringBuilder
* difference with String:
* 1、比String效率高
* 2、比String节省内存
* */
public class StringBufferAndBuilderDemo {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer();
//append,追加
sb.append("我爱");
sb.append("宋");
sb.append("+小狗");
System.out.println(sb.toString());//我爱宋+小狗
//insert,根据索引插入
sb.insert(0,"哈哈");
sb.insert(1,"?");
System.out.println(sb.toString());//哈?哈我爱宋+小狗
//replace,从索引start开始替换,不取end
sb.replace(1,2,"韩小信");
System.out.println(sb.toString());//哈韩小信哈我爱宋+小狗
//delete,根据索引删除
sb.delete(8,9);
System.out.println(sb.toString());//哈韩小信哈我爱宋小狗
//翻转
sb.reverse();
System.out.println(sb.toString());//狗小宋爱我哈信小韩哈
//清空
sb.delete(0,sb.length());
System.out.println(sb.toString());
}
}
StringBuilder的功能方法和StringBuffer几乎一样,效率高,但线程不安全,单线程中使用StringBuilder
验证:
/***
* 对String、StringBuffer、StringBuilder的效率进行验证
*/
public class StringVertifyDemo {
public static void main(String[] args) {
// long start1=System.currentTimeMillis();//返回当前时间
// String str1="";
// for (int i = 0; i < 99999; i++) {
// str1+=i;
// }
// //System.out.println(str);
// long end1=System.currentTimeMillis();
// System.out.println("用时:"+(end1-start1));//22177ms
//测试StringBuffer和StringBuilder时要注解掉上面的Sting,否则可能会受到常量池中缓存的影响
long start2=System.currentTimeMillis();//返回当前时间
StringBuffer str2=new StringBuffer();
for (int i = 0; i < 999999; i++) {
str2.append(i);
}
//System.out.println(str);
long end2=System.currentTimeMillis();
System.out.println("用时:"+(end2-start2));//76ms
long start3=System.currentTimeMillis();//返回当前时间
StringBuilder str3=new StringBuilder();
for (int i = 0; i < 999999; i++) {
str3.append(i);
}
//System.out.println(str);
long end3=System.currentTimeMillis();
System.out.println("用时:"+(end3-start3));//37ms
}
}
本文来自博客园,作者:一只快乐的小67,转载请注明原文链接:https://www.cnblogs.com/sp520/p/15794738.html