String-StringBuffer-StringBuilder,Comparable-comparator

String

  • 1.String是final类,不可被继承
  • 2.内部是value[]的数组
private final char value[];
  • 3.不可变字符串
String s1 = "abc"; //字面量方式,"abc"被放到了常量池中
String s2 = "abc";  //这里s1 和 s2指向同一个地址
//这里想要修改s1,但是不能修改s1,实际它是ccc被放到另外一个地址,
//这里把ccc的地址赋给了s1, s2还是指向abc的地址
s1 = "ccc";

s3 = s1 + "def";  //结果abcdef;这里把abcdef的地址赋值给了s3,s1还是指向abc的地址

测试

String s1="hello";
String s2="world";
String s3="hello"+"world";
String s4=s1+"world";
String s5=s1+s2;
String s6=(s1+s2). intern();
System.out.print1n(s3==s4);//false
System.out.printin(s3==s5);//false
System.out.print1n(s4==s5);//false
System.out.print1n(s3==s6);//true

/**结论
1. 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量。
2. 只要其中有一个是变量,结果就在堆中
3. 如果拼接的结果调用intern()方法,返回值就在常量池中
*/

StringBuffer

  • 可变字符序列,线程安全,效率低,底层使用char[] 存储

源码刨析:和(StringBuilder类似)

// StringBuffer类是final,不可被继承,且继承了AbstractStringBuilder类
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
//该类是AbstractStringBuilder抽象的
abstract class AbstractStringBuilder implements Appendable, CharSequence{
    char[] value;  //string底层是数组,且非final的,表示可变string

    int count;    //count记录数组里面有几个真实的元素
}

//以此为例
new StringBuffer("abc");

public StringBuffer(String str) {
        super(str.length() + 16);  //①,调用父类(AbstractStringBuilder)的构造器
        append(str); //②,把str="abc"添加到value数组中
    }
//①
AbstractStringBuilder(int capacity) {
        value = new char[capacity];  //底层是数组,创建了capacity = 19的数组
    }
//②
@Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str); //③,调用父类的append方法
        return this; //返回当前对象
    }
//③
public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull(); //④ 把"null"加入value数组中
        int len = str.length();
        ensureCapacityInternal(count + len);//⑤扩容检查,count = 0,len = 3
        str.getChars(0, len, value, count);//⑦ 把str加入到vlaue[]中
        count += len;
        return this;
    }
//④
private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);  //检查数组长度是否够用
        final char[] value = this.value; //定义final变量,表示该数组 引用 不可修改
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }
//⑤
private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code,容量不够则扩容
        if (minimumCapacity - value.length > 0) {  //3-19,
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity)); //⑥
        }
    }
//⑥
private int newCapacity(int minCapacity) {
        // overflow-conscious code,value的长度*2+2;
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity  value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); //添加字符串到value数组中
    }

StringBuffer中定义了这样一个变量

//StringBuffer中定义了这样一个变量
private transient char[] toStringCache;
/**
看toString()方法
*/
@Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
//StringBuilder的toString()
@Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

StringBuilder

  • 可变字符序列,线程不安全,效率高,底层使用char[] 存储

三者效率问题(从高到低): StringBuilder > StringBuffer > String

Comparable,Comparator

  • String,包装类等重写了compareTo()方法,默认按照从小到大排序
  • Comparable:自然排序,位于java-lang包下
  • Comparator:定制排序,位于java-util包下
//example 1: String实现了Comparable接口.并且重写了compareTo()方法
        String[] strings = new String[]{"d","a","c","b"};
        Arrays.sort(strings);
        System.out.println(Arrays.toString(strings));  //result:[a, b, c, d]

//example 2: 自定义类让其继承Comparable接口
/**
结果:
[ Goods{name='dell', price=15},
  Goods{name='apache', price=25},
  Goods{name='xiaomi', price=25},
  Goods{name='huawei', price=35},
  Goods{name='lenovo', price=55}
]
/
public class CompareTest {
    public static void main(String[] args) {
        Goods[] goods = new Goods[5];
        goods[0] = new Goods("xiaomi",25);
        goods[1] = new Goods("dell",15);
        goods[2] = new Goods("lenovo",55);
        goods[3] = new Goods("huawei",35);
        goods[4] = new Goods("apache",25);

        Arrays.sort(goods);
        System.out.println(Arrays.toString(goods));
    }
}

class Goods implements Comparable{
    private String name;
    private int price;

    public Goods() {
    }

    public Goods(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Goods{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }

    /**
    * 先按照价格从小到大排序,再按照名称从小到大排序
    * */
    @Override
    public int compareTo(Goods o) {
        if (this.getPrice() != o.getPrice())
            return Double.compare(this.getPrice(),o.getPrice()); //double的包装类 的排序
        else
            return getName().compareTo(o.getName());  //String的排序
    }

}
//也可以用Comparator接口
public static void main(String[] args) {
        Goods[] goods = new Goods[5];
        goods[0] = new Goods("xiaomi",25);
        goods[1] = new Goods("dell",15);
        goods[2] = new Goods("lenovo",55);
        goods[3] = new Goods("huawei",35);
        goods[4] = new Goods("xiaomi",15);

        //Arrays.sort(goods);
        Arrays.sort(goods, new Comparator() {
            @Override
            public int compare(Goods o1, Goods o2) {
                //先按照名称从小到大排序,再按照价格升序
                if (o1.getName().equals(o2.getName()))
                    return Double.compare(o1.getPrice(),o2.getPrice());

                return o1.getName().compareTo(o2.getName());

            }
        });
        System.out.println(Arrays.toString(goods));
    }
/**
结果:
[ Goods{name='dell', price=15},
  Goods{name='huawei', price=35},
  Goods{name='lenovo', price=55},
  Goods{name='xiaomi', price=25},
  Goods{name='xiaomi', price=15}
]
*/

Original: https://www.cnblogs.com/huyuqing/p/14322240.html
Author: 先生胡
Title: String-StringBuffer-StringBuilder,Comparable-comparator

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/567211/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球