java中String类型
1. JVM(内存图)
要明白java中的String类型的存储,首先要搞清楚JVM的内部
- 方法区(主要用于存放方法)
- 类常量池
- 静态常量池
- 字符串常量池(避免频繁的创建和销毁字符串,实现了数据的共享,提高了系统的性能)
- 栈区
- 堆区
- 程序计数区
- 本地方法栈
2. 创建一个字符串
public class Main{ public static void main(String[] args){ String s1 = "abc"; } }
首先在JVM中运行main方法,在栈区中为main方法开辟一块内存,然后在main方法的内存中创建了一个String类型的变量,此时,在方法区中的字符串常量池中就会构造一个"abc" 的字符串,并将该字符串的地址交给String类型的变量
public class Main{ public static void main(String[] args){ String s1 = new String("abc"); } }
这样就会在堆区中开辟一块内存,然后将地址存储在s1中,但实际上堆中开辟的那个块内存,引用了常量池中的abc
String s1 = new String("abc");
所以说上面这就话在内存中开辟了两块或者三块的内存(如果常量池中有就是两块,如果常量池中没有就在常量池中也开辟一块空间,所以是三块)
3. 字符串的比较
public class Main{ public static void main(String[] args){ String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); System.out.println(s1 == s2); System.out.println(s1 == s3); } }
输出结果:
true false
等于号在java中默认比较的是地址,s1和s2都是指向字符串常量池中创建的字符串,所以地址相等,所以s1等于s2
但是对于s3而言,new了一个新的对象,该对象指向了字符串常量池中的字符串,所以s1不等于s3
public class Main{ public static void main(String[] args){ String s1 = "123"; String s2 = "456"; String s3 = s1+s2; String s4 = "123456"; String s5 = "123"+"456"; System.out.println(s3 == s4); System.out.println(s4 == s5) } }
对于字符串s1和s2的拼接,实际上是调用了java中String类中的StringBulder.toString();实际上也就是new了一个新的字符串,所以地址不一样,
但是对于s5中的拼接,会在编译的时候直接常量合并,所以说可以直接将s4和s5看成一样的
false true
4. 字符串常用方法
String s = "abc"; System.out.println(s.length()); // 获取字符串长度 System.out.println(s.charAt(1)); // 获取字符串指定字符的值,下标从0开始 System.out.println(s.codePointAt(1)); // 获得字符串指定字符的值对应的编码值,下标从零开始,与上面一个类似 System.out.println(s.equals("abc")); // 比较字符串的内容 System.out.println(s.substring(0,3)); // 该字符串的从2到第二个字符 即:[0, 3) System.out.println(s.indexOf("a")); // 查找某个字符串所在的位置,也可以是一个字符串,也可以跳过多少个字符开始寻找,如果不存在,返回-1 System.out.println(s.lastIndexOf("a")); // 与上面的方法类似,不过是从结尾开始寻找 System.out.println(s.startsWith("a")); // 是否是以a开头的字符串 System.out.println(s.endsWith("c")); // 是否是以c结尾 System.out.println(s.contains("b")); // 是否包含b字符 System.out.println(s.replace("a","c")); // 将字符a替换成字符c System.out.println(s.toUpperCase()); // 将字符转化成大写 System.out.println(s.toLowerCase()); // 将字符转化成小写 System.out.println(s.trim()); // 将字符串中的开头结尾中的空格去掉
5. 可变字符串(频繁修改时使用)
标签:java,String,s1,System,字符串,println,out From: https://www.cnblogs.com/ning23/p/180830111. StringBuilder(线程不安全)
2. StringBuffer(线程安全)
进程:计算机中最小的资源分配单位
线程:计算机中最小的执行单位
3. 常用的Api
StringBuilder sb = new StringBuilder("abcdef"); System.out.println(sb.append("a")); // 在sb中添加一个字符或一个字符串 System.out.println(sb.insert(1, "ab")); // 在sb中指定位置插入 System.out.println(sb.delete(2, 3)); // 删除sb中指定位置的字符[2, 3) System.out.println(sb.deleteCharAt(3)); // 删除指定位置上的字符 sb.setCharAt(2, 'a'); // 修改制定位置上的字符 System.out.println(sb.reverse()); // 字符串反转