相关文章:
- 《常用类 (一) ----- Arrays数组工具类》
- 《常用类 (二) ----- Math类》
- 《常用类 (三) ----- BigDecimal和BigInteger大数类》
- 《常用类 (四) ----- Random随机数类》
- 《常用类 (五) ----- Date日期类和Calender日历类》
- 《常用类 (六) ----- String类与字符串》
- 《常用类 (七) ----- 包装类》
Java中字符串存储原理
- 在Java中只要是用
""
双引号括起来的都属于String对象。例如:“abc”,“def”,“kll”,"momo"属于4个不同的字符串对象。 - 我们创建的字符串对象是直接存储在JVM的“方法区”的“字符串常量池”当中。例如:“abc”,"def"这些字符串创建后就直接存储在了JVM的“方法区”的“字符串常量池”中了,凡是用
""
双引号括起来的,都会储存在“字符串常量池”中。 - 不可变性:在字符串"abc","def"存储在“字符串常量池”中后,我们不能再去改变它的内容。
- 复用性:只要在”字符串常量池“已经存在的字符串,我们就可以用引用反复去指向它,不用创建新的字符串。
- 在字符串进行拼接的时会产生新的字符串在“字符串常量池”中。
示例:
// 这两行代码表示在底层创建了3个字符串对象,存储在字符串常量池中
String s1 = "abcdef";
String s2 = "xy" + "abcdef";

String s1 = "abcdef";
String s2 = "xy" + "abcdef";
// s3指向new出来的堆内存空间,该空间中存储了"xy"字符串在字符串常量池中的地址
String s3 = new String("xy");

注意:
-
下列代码一共创建了几个对象?
String s1 = new String("abc"); String s2 = new String("abc"); //答:new了2个对象在堆区,"abc"字符串对象在字符串常量池中,一共3个对象。
-
下列情况是true还是false?
String s1 = "hello"; String s2 = "hello"; String s3 = new String("hello"); String s4 = new String("hello"); // s1和s2指向方法区字符串常量池中同一块内存 System.out.println(s1 == s2);// true // s1指向常量池中的内存,s3指向堆中内存 System.out.println(s1 == s3);// false // s3和s4指向堆中不同的内存 System.out.println(s3 == s4);// false // s3和s4的内容相等 System.out.println(s3.equals(s4));// true
-
关于返回值为String类型的方法
Integer a = 1000; Integer b = 1000; Integer c = 2000; // 等价String s1 = new String(a.toString()); String s1 = a.toString(); // 等价String s2 = new String(b.toString()); String s2 = b.toString(); // 等价String s3 = new String(c.toString()); String s3 = c.toString(); // s1、s2、s3都指向不同的堆内存地址,所以为false System.out.println(s1 == s2);// false System.out.println(s1 == s3);// false
String类常用的构造方法
-
直接用String引用指向字符串
String s = "abc";
-
向构造方法中传入字符串
String s = new String("abc");
-
向构造方法中传入byte数组(将byte数组转换为字符串)
byte[] bytes = {97,98,99};// 97是a,98是b,99是c String s = new String(bytes);// abc
-
向构造方法中传入byte数组并设置偏移量和长度(将byte数组中的一部分转换为字符串)
byte[] bytes = "abc"; // 从bytes下标1开始传入长度为2的串 String s= new String(s,1,2); // bc
-
向构造方法中传入char数组(将char数组转换为字符串,对比下面将字符串转换为char数组的方法)
char[] chars = {"莫", "莫", "大", "胖", "子"}; String s = new String(chars);
-
向构造方法中传入char数组并设置偏移量和长度(将char数组中的一部分转换为字符串)
char[] chars = {"莫", "莫", "大", "胖", "子"}; String s = new String(chars,2,3); "大胖子"
String类中的常用方法
一、基本方法
-
判断某个字符串是否为空字符串""——
boolean isEmpty()
-
返回字符串长度——
int length()
-
在字符串尾部连接指定字符串——
String concat(String s)
-
去除字符串前后空格——
String trim()
-
将非字符串的内容转换为字符串——
static String valueOf(非字符串内容)
String sBoolean = String.valueOf(true);// "true" String sInt = String.valueOf(1);// "1" String sDouble = String.valueOf(11.23)// "11.23" //当String.valueOf(传入一个对象引用的时候会自动调用其toString方法)
二、找查
-
返回字符串指定下标字符——
char charAt(int index)
-
返回字符串指定下标之后的子串——
String substring(int begin)
-
返回字符串指定下标区间(左闭右开)的子串——
String substring(int begin, int end)
String s1 = "Momo123"; String s2 = s1.substring(2, 4);// "mo",包含开始下标元素,不包含结束下标元素
-
返回字符串中某个子字符串第一次出现的头部下标——
int indexOf(String s)
-
返回字符串中某个子字符串最后一次出现的头部下标——
int lastIndexOf(String s)
-
判断字符串是否以某个子串开始——
boolean startsWith(String prefix)
-
判断字符串是否以某个子串结尾——
boolean endsWith(String suffix)
-
判断字符串是否含有某个子串——
boolean contains(String s)
三、修改与拆分
-
将字符串中所有与目标字符串相同的子串替换为指定字符串——
String replace(String target, String replacement)
String s1 = "http://www.baidu.com"; String s2 = s1.replace("http://", "https://");// "https://www.baidu.com" String s3 = "1 + 1 = 2"; String s4 = s3.replace("1","2");// "2 + 2 = 2"
-
把字符串以给定子串为为分界线拆分到String数组中——
String[] split(String s)
String date = "2020-11-30"; String[] ymd = date.split("-");// {"2020", "11", "30"}
四、转换
- 将字符串转换为char数组——
char[] toCharArray()
- 将字符串转换为byte数组——
byte[] getBytes()
- 将字符串中所有大写转换为小写字母——
String toLowerCase()
- 将字符串中所有小写转换为大写字母——
String toUpperCase()
五、比较
- 按照字典顺序比较字符串大小——
int compareTo(String anotherString)
// 字符串从第一个字母与另一个字符串从第一个字母依次比较,能分大小就不比后面的了 int result1 = "abc".compareTo("abc");// 前后相等,返回0 int result2 = "abcd".compareTo("abce");// 前小后大,返回-1 int result3 = "abce".compareTo("abcf");// 前大后小,返回1
- 忽略大小写判断两个字符串是否相等——
boolean equalsIgnoreCase(String anotherString)
StringBuffer
一、前言:
当进行字符串拼接的时候,例如"abc" + “def” 一共会创建3个字符串对象在“字符串常量池”中,如果有大量的字符串拼接则产生的新字符串会在常量池中占用大量内存,StringBuffer就是用来解决这个问题的,其底层是一个byte数组,因此王StringBuffer中存放字符串实际上放在byte数组中了,默认初始化容量为16。
二、常用方法
方法 | 说明 |
---|---|
append(数据值) | 把指定数据值追加到字符串末尾 |
delete(int start, int end) | 删去指定范围的子串 |
deleteCharAt(int index) | 删去指定下标的字符 |
insert(偏移量, 数据值) | 插入数据值到指定下标 |
reverse() | 翻转字符串 |
// 创建一个指定容量为32的字符串缓冲区对象(byte数组)
StringBuffer buffer = new StringBuffer(32);
// 可以拼接任何基本数据类型到字符串缓冲区中
// 如果在拼接数据的时候容量满了会进行数组扩容(arrcopy)
// 所以使用StringBuffer的时候最好指定一个合适的容量优化内存占用(扩容越少效率越高)
buffer.append("a");
buffer.append(3.14);
buffer.append(true);
System.out.println(buffer.toString());// "a3.14true"
StringBuffer buffer2 = new StringBuffer("123");
buffer2.append("abc");
buffer2.insert(1,"KLL");
System.out.println(buffer2);// 1KLL23abc
buffer2.delete(1,4);
System.out.println(buffer2);// 123abc
System.out.println(buffer2.reverse());// cba321
StringBuffer和StringBuilder的区别
StringBuffer中的方法都有synchronized关键字修饰,而StringBuilder中没有,前者线程安全,后者非线程安全。