• 二、字符串 String


    二、字符串 String

    String 不是基本数据类型,是一个用final 修饰的最最最最最最常用的引用数据类型!

    小拓展:String 为什么可以直接赋值为一个字符串?

    1、存储结构

    底层就是一个 char数组

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        /** 该值用于字符存储. */
        private final char value[];
    
        /** 缓存字符串的哈希码 */
        private int hash; // 默认为0
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、4个重要(必须知道)构造

    就 JDK 1.8 而言,String 有 16 个构造方法(其中有 2 个是废弃的)

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
    
        /* 以 String 为参数 */
        public String(String original) {
            this.value = original.value;
            this.hash = original.hash;
        }
    
        /* 以 char[] 为参数 */
        public String(char value[]) {
            this.value = Arrays.copyOf(value, value.length);
        }
    
        /* 以 StringBuffer 为参数 */
        public String(StringBuffer buffer) {
            synchronized(buffer) {
                this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
            }
        }
       
        /* 以 StringBuilder 为参数 */
        public String(StringBuilder builder) {
            this.value = Arrays.copyOf(builder.getValue(), builder.length());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3、String.equals

    String.equals 重写了 Object.equals

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence {
        
        public boolean equals(Object anObject) {
            // 对象引用相同直接返回true
            if (this == anObject) {
                return true;
            }
            
            // 必须是String类型才有比较的必要
            if (anObject instanceof String) {
                String anotherString = (String)anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    // 把两个字符串转成char[]逐一比对
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                            return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    4、常用方法

    1. indexOf():返回第一次出现的位置,没有返回-1
    2. lastIndexOf():返回最后一次出现的位置,没有返回-1
    3. contains():判断包含
    4. toUpperCase():转至大写
    5. toLowerCase():转至小写
    6. length():返回字符串你长度
    7. trim():去掉首尾空格
    8. .replace():替换
    9. split():拆分数组
    10. join():字符串数组转字符串
    11. endsWith():判断结尾包含
    12. startsWith():判断起始包含
    13. equalsIgnoreCase():忽略大小写比较
    14. isEmpty():判空
    15. .substring():截取

    5、为何 final 修饰

    对于这样设计的好处,Java语言之父 James Gosling的回答是:

    他会更倾向于使用final;因为它能够缓存结果,当你在传参时不需要考虑谁会修改它的值

    如果是可变类的话,则有可能需要重新拷贝出来一个新值进行传参,这样在性能上就会有一定的损失

    迫使 String类设计成不可变的另一个原因是安全

    1. 安全
    2. 高效

    6、String、StringBuilder、StringBuffer

    StringBuffer 、StringBuilder 都是操作自身的 char[] 来实现字符串的操作;String每次修改都是赋值一个全新的字符串,之前的字符串依然存在,但是很快会被当成垃圾回收掉。

    StringBuffer 使用 synchronized 来保证线程安全

    String 常用两种创建方式:

    /**
     * s1先去字符串常量池查看是否有 "aaa" 字符串,如果有直接返回常量句柄;
     * 如果没有此字符串,先在字符串常量池中创建这个字符串,然后再返回常量句柄
     */
    String s1 = “aaa”;
    
    /**
     * s2直接在堆上开辟一个空间,存放 "aaa",只有调用了intern()方法才会把这个
     * 字符串存到字符串常量池
     */
    String s2 = new String(“aaa”);
    
    // 验证
    System.out.println(s1 == s2); // false
    String s3 = s2.intern();
    System.out.println(s1 == s3); // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Android 基础知识3-4 Activity的声明周期
    预处理指令
    做BI智能数据分析,奥威BI系统是专业的
    SpringBoot的日志系统(日志分组、文件输出、滚动归档)
    【reverse】新160个CrackMe之116-REM-KeyGenME#10——脱壳、去背景音乐、识别反调试
    nginx(五十七)ngx_http_upstream模块(二)一致性hash算法
    jQuery基础教程
    【深入理解C++】可调用对象、std::function、std::bind()
    深入理解Python中的面向对象编程(OOP)【第129篇—Scikit-learn的入门】
    Container容器
  • 原文地址:https://blog.csdn.net/qq_30769437/article/details/126646900