Java【String类】的详解(二) 最详细了 你一学就会

94 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

字符串常量池

字符串常量池在JVM中是StringTable类,实际上是一个固定大小的HashTable

不同JDK版本下字符串常量池位置大小是不同的

捕获12.PNG

1. 通过字符串常量进行赋值

public static void main(String[] args) {
            String s1 = "hello";
            String s2 = "hello";
 
            System.out.println(s1 == s2); // true
    }

无标题.png

s1和str的地址是不相同的,所以比较就是false

2.通过new创建String类对象

public static void main(String[] args) {
            String s1 = "hello";
            String s2 = "hello";
            String str = new String("hello");
            System.out.println(s1 == s2); // true
            System.out.println(s1 == s3); // false
    }

3. intern方法

没使用intern方法前

public static void main(String[] args) {
        char[] ch = new char[]{'a', 'b', 'c'};
        String s1 = new String(ch); 

        String s2 = "abc"; 
        System.out.println(s1 == s2);//false
}

使用intern方法后

public static void main(String[] args) {
        char[] ch = new char[]{'a', 'b', 'c'};
        String s1 = new String(ch); 
        s1.intern();
        String s2 = "abc";
        System.out.println(s1 == s2);
}

所以intern的作用是:检查s1所指向的对象在常量池中是否存在,

如果不存在就把当前对象入池;存在就返回常量池中的对象

4. 字符串不可变性

61e3bf7b2b934ff1841e6f55b66e4133.png

090760c7697b46f6bd46c8530b983d91.png

6d6029767e234ee6b2d88ba44435856a.png

5. StringBuilder和StringBuffer

这里先看一下String,

String类是一个不可变类,即创建String对象后,该对象中的字符串是不可改变的,直到这个对象被销毁。

1.StringBuffer与StringBuilder

StringBuffer与StringBuilder都继承自AbstractStringBuilder类,AbstractStringBuilder中也是使用字符数组保存字符串,是可变类。

并且都提供了一系列插入、追加、改变字符串里的字符序列的方法,它们的用法基本相同

  1. 下面可以看一下二者的用法

StringBuilder.append:添加任意类型数据的字符串形式,并返回当前对象自身

 public static void main(String[] args) {
 
        StringBuilder stringBuilder= new StringBuilder();
        stringBuilder.append("hello");
        stringBuilder.append(" world");
 
        String s = stringBuilder.toString();
        System.out.println(s);
    }

StringBuilder.reverse 逆置字符串

public static void main(String[] args) {

    StringBuilder stringBuilder= new StringBuilder();
    stringBuilder.append("hello");
    stringBuilder.append("world");

    stringBuilder.reverse();
    System.out.println(stringBuilder);//dlrowolleh
}

StringBuffer.apppend

public static void main(String[] args) {
    StringBuffer stringBuffer= new StringBuffer();
    stringBuffer.append("hello");
    stringBuffer.append("world");
    
    System.out.println(stringBuffer);//helloworld
}

StringBuffer.reverse 逆置字符串

public static void main(String[] args) {
    StringBuffer stringBuffer= new StringBuffer();
    stringBuffer.append("hello");
    stringBuffer.append("world");

    stringBuffer.reverse();
    System.out.println(stringBuffer);//dlrowolleh
}

StringBuilder和StringBuffer二者的区别

打开二者append的原码,观察发现 二者相比较,StringBuffer更安全,但并不是说StringBuffer比StringBuilder要更好,

因为StringBuffer的安全是建立在相对来说降低效率和耗费资源的基础之上的。

二者就方法来说,基本都是一样的。

StringBuffer和StringBuilder和String的区别

(1)String内容不可以修改,而StringBuffer与StringBuilder,提供了一系列插入、追加、 改变字符串里的字符序列的方法,并且修改不产生新的对象,而是在原对象的基础上修改

(2)就三者效率进行比较

     StringBuilder > StringBuffer > String

(3)从安全性和操作数据量来比较

     如果要操作的数量比较小,应优先使用String类;

     如果是在单线程下操作大量数据,应优先使用StringBuilder类;

     如果是在多线程下操作大量数据,应优先使用StringBuffer类。

(4)StringBuffer使用了缓存区,StringBuilder没有使用缓存区,所以没有修改数据的情况下,多次调用StringBuffer的toString方法获取的字符串是共享底层的字符数组的。
而StringBuilder不是共享底层数组的,每次都生成了新的字符数组

6. 就本篇所提到的方法进行大致总结

方法 作用
charAt() 输入下标,找单个字符
indexOf() 从前往后找,找字符或字符串,需要返回下标
lastIndexOf() 从后往前找,找字符或字符串,需要返回下标
split() 对字符串进行拆分,注意特殊字符,需要转义
repalce() 替换字符串中的字符
replace()/replaceAll() 替换字符串中的字符串
replaceFrist() 替换字符串中的首个字符串
subString() 截取字符串
String.valueof() 数字转字符串
Integer.parselnt() / Integer.valueof() 字符串转数字
toUpperCase() 字母小写转大写
toLowerCase() 字母大写转小写
toCharArray() 字符串转数组
new String() 数组转字符串
format() 格式化输出
String.equals() 比较字符串相不相等,返回boolean类型
String.compareTo() 比较字符串大小关系,返回int 类型
equlsTolgnoreCase() 忽略字母大小写,比较是否相等
trim() 去掉字符串中,首尾部空格,保留中间空格