美文网首页
String、StringBuffer、StringBuilde

String、StringBuffer、StringBuilde

作者: 有腹肌的豌豆Z | 来源:发表于2020-08-25 11:17 被阅读0次

    一、Java String 类——String字符串常量

    简介

    • String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。
    • 因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
    • 与包装类类似,String类也是不可变类,即对象一旦创建,就没有办法修改了。String类也声明为了final,不能被继承,内部char数组value也是final的,初始化后就不能再变了。
        public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
       
       /** 
        *The value is used for character storage. 
        */
        private final char value[];
    
    • String 是 final 类,不能被继承。对于已经存在的 Stirng 对象,修改它的值,就是重新创建一个对象
    • String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且浪费大量优先的内存空间
    String 对象的两种创建方式。
    String str1="abcd";
    String str2=new String("abcd");
    System.out.println(str1==str2);// false
    
    • 这两种不同的创建方法是有差别的,第一种方式是在常量池中那对象。
    • 第二种方式是直接在对内存空间创建一个新的对象。


    String pool ,String 类型的常量池比较特殊。
    • 检查字符串池里面有没有“XXX”的内容,如果有,则不会从创建新的字符串对象。将已有对象的地址返回给那个引用。
    • 直接使用双引号声明出来的String对象会直接存储在常量池中。
    • 如果不是用双引号声明的String对象,可以使用String提供的intern方法。String.intern()是一个Native方法,它的作用是:
      如果运行时常量池中已经包含一个等于词String对象内容的字符串,则返回常量池中该字符串的引用;
      如果没有,则在常量池中创建与此String内容相同的字符串,并返回常量池中创建的字符串的引用。
    String s1 = new String("计算机");
    String s2 = s1.intern();
    String s3 = "计算机";
    System.out.println(s2); // 计算机
    System.out.println(s1==s2); // false 因为一个是堆内存中的String对象,一个是常量池中的String对象。
    System.out.println(s2==s3);// true 应为两个都是常量池中的对象。
    
    String 字符串拼接
    String str1 = "str";
    String str2 = "ing";
    
    String str3 = "str"+"ing"; // 常量池中的对象
    String str4 = str1+str2; // 在堆上创建的新的对象 
    String str5 = "string"; // 在常量池中的对象 
    
    System.out.println(str3==str4); // false
    System.out.println(str3==str5); // true
    System.out.println(str4==str5); // false
    
    String s1 = new String("abc"); // 这句话创建了几个对象 ?
    • 创建了两个对象。
    • “abc”这个是常量池对象
    • 只要使用 new 便是创建新的对象
    String.format()占位符替换
    String常用函数
    //判断字符串是否为空
    public boolean isEmpty()
    
    //获取字符串长度
    public int length()
    
    //取子字符串  截取
    public String substring(int beginIndex)
    public String substring(int beginIndex, int endIndex)
    
    //在字符串中查找字符或子字符串,返回第一个找到的索引位置,没找到返回-1
    public int indexOf(int ch)
    public int indexOf(String str)
    
    //从后面查找字符或子字符串,返回从后面数的第一个索引位置,没找到返回-1
    public int lastIndexOf(int ch)
    public int lastIndexOf(String str)
    
    //判断字符串中是否包含指定的字符序列。回顾一下,CharSequence是一个接口,String也实现了CharSequence
    public boolean contains(CharSequence s)
    //判断字符串是否以给定子字符串开头
    public boolean startsWith(String prefix)
    
    //判断字符串是否以给定子字符串结尾
    public boolean endsWith(String suffix)
    
    //与其他字符串比较,看内容是否相同
    public boolean equals(Object anObject)
    
    //忽略大小写,与其他字符串进行比较,看内容是否相同
    public boolean equalsIgnoreCase(String anotherString)
    
    //String也实现了Comparable接口,可以比较字符串大小
    public int compareTo(String anotherString)
    
    //还可以忽略大小写,进行大小比较
    public int compareToIgnoreCase(String str)
    
    //所有字符转换为大写字符,返回新字符串,原字符串不变
    public String toUpperCase()
    
    //所有字符转换为小写字符,返回新字符串,原字符串不变
    public String toLowerCase()
    
    //字符串连接,返回当前字符串和参数字符串合并后的字符串,原字符串不变
    public String concat(String str)
    
    //字符串替换,替换单个字符,返回新字符串,原字符串不变
    public String replace(char oldChar, char newChar)
    
    //字符串替换,替换字符序列,返回新字符串,原字符串不变
    public String replace(CharSequence target, CharSequence replacement)
    
    //删掉开头和结尾的空格,返回新字符串,原字符串不变
    public String trim()
    
    //分隔字符串,返回分隔后的子字符串数组,原字符串不变
    public String[] split(String regex)
            //例如,按逗号分隔"hello,world":
            String str = "hello,world";
                    String[] arr = str.split(","); //arr[0]为"hello", arr[1]为"world"。
    

    二、StringBuffer

    • Java.lang.StringBuffer线程安全的可变字符序列。
    • 一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
    • 可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
    • StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。

    三、StringBuilder

    • java.lang.StringBuilder一个可变的字符序列是5.0新增的。
    • 此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
    • 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

    四、StringBuffer与StringBuilder的线程安全性问题

    • StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。
    • 注意:是不是String也不安全呢?事实上不存在这个问题,String是不可变的。线程对于堆中指定的一个String对象只能读取,无法修改。试问:还有什么不安全的呢?

    相关文章

      网友评论

          本文标题:String、StringBuffer、StringBuilde

          本文链接:https://www.haomeiwen.com/subject/yibojktx.html