String s1 = new String("abc");
String s2 = "abc";
第一,在堆中创建一个String对象,他的value为abc,检查到常量池没有abc这个字符串,于是在字符串常量池中创建并将其关联到String对象上。将这个String对象的内存地址值,赋值给栈中S1变量。
第二行中,检查到常量池中已经存在abc这个字符串,所以直接将地址赋给了变量s2.
至于底层如何关联,可以理解为String中有个value属性,可以通过它进行关联。至于详细讲述,感兴趣的话可以自行查阅《Java编程思想》之类的书籍。
建议先建立知识体系为主,旁枝末节容后再议
String s1 = "abc"; //s1在栈中
String s2 = "abc";
String s3 = new String("abc"); //s3在堆中
s1==s2 //true
s1==s3 //false
s1.equals(s3) //true //String重写了equals,比较内容
String string = new String();
String string2 = "";
System.out.println(string==string2); //false
public class TestString {
public static void main(String[] args) {
String string="abc";
System.out.println(string);
//charAt
System.out.println(string.charAt(1));
//indexOf
System.out.println(string.indexOf('b')); //char自动转换为int
System.out.println(string.indexOf("bc")); //字符串
System.out.println(string.indexOf(98)); //int
System.out.println(string.indexOf('l')); //-1
//lastIndexOf
String string2 = "helloworld";
System.out.println(string2.indexOf('o',5)); //6
System.out.println(string2.lastIndexOf('o',3)); //-1 //反向搜索
//replace 不改变原字符串 只操作了方法区的常量池
System.out.println(string2.replace('o', 'p')); //hellpwprld
System.out.println(string2); //helloworld
//substring 不改变原字符串 只操作了方法区的常量池
System.out.println(string2.substring(3)); //loworld 一直到结尾
System.out.println(string2.substring(3,7)); //lowo 含头不含尾
System.out.println(string2); //helloworld
//toUpperCase toLowerCase 不改变原字符串 只操作了方法区的常量池
System.out.println(string2.toUpperCase()); //HELLOWORLD
System.out.println(string2); //helloworld
System.out.println("JAVA".toLowerCase()); //java
//trim 去掉前后空格 不改变原字符串 只操作了方法区的常量池
String string3 = " hello world";
System.out.println(string3.trim()); //hello world
System.out.println(string3); // hello world
//split
String string3 = "1,2,3,4,5";
String[] arr = string3.split(",");
System.out.println(Arrays.toString(arr)); //[1, 2, 3, 4, 5]
//toCharArray
String string4 = "abbccdde";
System.out.println(Arrays.toString(string4.toCharArray())); //[a, b, b, c, c, d, d, e].
//getBytes
String string5 = "abbccdde";
byte[] b = string5.getBytes();
System.out.println(Arrays.toString(b)); //[97, 98, 98, 99, 99, 100, 100, 101]
}
}
/*String的构造方法*/
String s1 = new String(); //创建了长度为0的字符串
String s2=null;//没有对象,只声明了栈变量
String s3 = new String("hello");
char[] c= {'a','b','c'};
String s4 = new String (c);
byte[] b= {97,98,99};
String s5=new String(b);
String s6 = new String(c,0,2); //开始位置,个数
String s7 = new String(b,0,2);
System.out.printf("s1=%s,s2=%s,s3=%s,s4=%s,s5=%s,s6=%s,s7=%s", s1,s2,s3,s4,s5,s6,s7);
//s1=,s2=null,s3=hello,s4=abc,s5=abc,s6=ab,s7=ab
String str1 = "abc";
String str2 = "a"+"b"+"c";
String str3 = new String("abc");
String str4 = str3+"";
String str5 = new String("abc");
System.out.println();
System.out.println("str1==str2:"+(str1==str2)); //str1==str2:true
System.out.println("str1==str3:"+(str1==str3)); //str1==str3:false
System.out.println("str1==str4:"+(str1==str4)); //str1==str3:false
System.out.println("str1==str5:"+(str1==str5)); //str1==str3:false
Java中的String为什么是不可变的? -- String源码分析 String:字符串常量池 java字符串常量值 String对象在Java的堆和常量池中的情况 JDK1.8版本java字符串常量池里存的是String对象还是引用? java内存分配和String类型的深度解析
boolean equals(Object obj)
//比较内容 boolean equalsIgnoreCase(Object obj)
boolean contains(String str)
//内部实现 indexof startsWith
endsWith
//equalsIgnoreCase
System.out.println(string.equalsIgnoreCase("ABC"));
//startsWith endsWith
System.out.println(string2.startsWith("h")); //true
System.out.println(string2.endsWith("d")); //true
/*compareTo*/
String aString = "apple";
String bString = "banana";
String catString = "cat";
String aString2 = "app";
//求两个字符串长度的最小值,循环,比较对应位置上的字母,如果不相同,则返回对应位置字母ASCII的差,如果在最小长度内都相同,则返回两个字符串的长度差
System.out.println(aString.compareTo(bString)); //-1
System.out.println(aString.compareTo(catString)); //-2
System.out.println(aString.compareTo(aString2)); //2
获取常量池中字符串对象,没有则创建
String string = new String("abc");
String string2 = string.intern(); //string2="abc";
System.out.println(string2);
System.out.println(string==string2); //false
//排序
String[] string = {"ab","bc","ce","cd"};
Arrays.sort(string);
System.out.println(Arrays.toString(string));
//查找子串的次数
String str = "nbasfafsdanbasdfaasnbafafasnbaafd";
String key = "nba";
int index = 0;
int count = 0;
while((index = str.indexOf(key, index))!=-1) {
index = index + key.length();
count++;
}
System.out.println(count);
//获取最大子串
String s1 = "qwerabcdtyuiop";
String s2 = "xcabcdvbn";
outer:
for(int i=0;i<s2.length();i++) {
for(int a=0,b=s2.length()-i;b!=s2.length()+1;a++,b++) {
String subString = s2.substring(a,b);
if(s1.contains(subString)) {
System.out.println(subString);
break outer;
}
}
}
//去掉两头空格
String string2 = " abc ";
int start = 0;
int end = string2.length()-1;
while(start<=end && string2.charAt(start)==' ') {
start++;
}
while(start<=end && string2.charAt(end)==' ') {
end--;
}
System.out.println(string2.substring(start,end+1));
字符串缓冲区,用于存储数据的容器
StringBuffer sBuffer = new StringBuffer();
//添加
StringBuffer sBuffer2 = sBuffer.append(1).append(true);
System.out.println(sBuffer); //1true
System.out.println(sBuffer==sBuffer2); //true
sBuffer.insert(1, "haha");
System.out.println(sBuffer); //1hahatrue
//删除
sBuffer.delete(1, 3);
System.out.println(sBuffer); //1hatrue
//查找 charAt indexOf lastIndexOf
//修改
sBuffer.replace(1, 3, "nba");
sBuffer.setCharAt(4, 'y');
System.out.println(sBuffer);
System.out.println(sBuffer.reverse());
sBuffer.setLength(0);
System.out.println(sBuffer.length());
线程不同步,不安全 解决StringBuffer需要判断锁的效率问题,适用于单线程 自动扩容 默认char[]16长度,大于16则乘以2再加2,如果大于34,则继续
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("helloworld");
sBuilder.append("world");
sBuilder.append("world");
sBuilder.append("world");
sBuilder.append("world");
sBuilder.append("world");
sBuilder.append("world");
System.out.println(sBuilder.length()); //40
System.out.println(sBuilder.capacity()); //70 (16*2+2)*2+2
StringBuilder比String连接效率高,因为连接其实也是用StringBuilder实现,还需要中间转换
public class Test {
public static void main(String[] args) {
String string = "";
for(int i=0;i<10;i++) {
string = string+i;
}
System.out.println(string);
StringBuilder sBuilder = new StringBuilder();
for(int i=0;i<10;i++) {
sBuilder.append(i);
}
System.out.println(sBuilder);
}
}