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 <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
//⑦
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > 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<Goods>{
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<Goods>() {
@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}
]
*/

String-StringBuffer-StringBuilder,Comparable-comparator的更多相关文章

  1. [置顶] String StringBuffer StringBuilder的区别剖析

    这是一道很常见的面试题目,至少我遇到过String/StringBuffer/StringBuilder的区别:String是不可变的对象(final)类型,每一次对String对象的更改均是生成一个 ...

  2. String | StringBuffer | StringBuilder 比较

    2016的第一天,我决定写一篇博客来纪念这一天,希望一年好运吧. String|StringBuffer|StringBuilder这三者在我们学习JAVASE核心API的时候常常出来,而且大多数入门 ...

  3. java中 String StringBuffer StringBuilder的区别

    * String类是不可变类,只要对String进行修改,都会导致新的对象生成. * StringBuffer和StringBuilder都是可变类,任何对字符串的改变都不会产生新的对象. 在实际使用 ...

  4. String,StringBuffer,StringBuilder的区别

    public static void main(String[] args) { String str = new String("hello...."); StringBuffe ...

  5. 关于String StringBuffer StringBuilder

    0. String对象的创建       1.关于类对象的创建,很普通的一种方式就是利用构造器,String类也不例外:String s=new String("Hello world&qu ...

  6. Java学习笔记--String StringBuffer StringBuilder

    String StringBuffer StringBuilder String http://docs.oracle.com/javase/7/docs/api/ 中文: http://www.cn ...

  7. String StringBuffer StringBuilder (转)

    转自:http://www.iteye.com/topic/522167 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却 ...

  8. 【Java基础】String StringBuffer StringBuilder

    String String是不可变的 我们都知道String不是基本数据类型,而是一个对象,并且是final类型的,不可变的.(public final class String) 查看以下代码: S ...

  9. String,StringBuffer,StringBuilder的区别及其源码分析

    String,StringBuffer,StringBuilder的区别这个问题几乎是面试必问的题,这里做了一些总结: 1.先来分析一下这三个类之间的关系 乍一看它们都是用于处理字符串的java类,而 ...

  10. final,finally,finalize有什么区别?String, StringBuffer, StringBuilder有什么区别?Exception和Error有什么区别?

    继上篇JVM学习之后,后面将分三期深入介绍剩余JAVA基础面试题,每期3题. 题目一.final,finally,finalize有什么区别? /*请尊重作者劳动成果,转载请标明原文链接:*/ /* ...

随机推荐

  1. QT-守护程序

    功能:手动选择EXE文件 1.手动开启应用,关闭应用 2.选择是否自动开启应用程序 3.将应用程序名称,操作,时间记入TXT文档 涉及:文件写入操作,基本控件使用.Windows命令使用 Github ...

  2. babel 的介绍及其配置

    vue/cli -- babel Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其 ...

  3. Codeforces Round #705 (Div. 2) B. Planet Lapituletti(镜像时钟) 思维

    传送门:  https://codeforces.com/contest/1493/problem/B 题目: Example input 5 24 60 12:21 24 60 23:59 90 8 ...

  4. 手把手教会 VS2022 设计 Winform 高DPI兼容程序 (net461 net6.0 双出)

    本文主要解决两个问题 C# Winform高DPI字体模糊. 高DPI下(缩放>100%), UI设计器一直提示缩放到100%, 如果不重启到100%,设计的控件会乱飞. 建立测试程序 新建.N ...

  5. HCIE笔记-第六节-CIDR与ICMP

    项目部 58人 地址:194.2.3.128 /26 研发部 100人 地址: 194.2.3.0/25 市场部 27人 地址: 194.2.3.192/27 财务部 15人 地址:194.2.3.2 ...

  6. 2021.12.07 [TJOI2013]最长上升子序列(Treap+DP)

    2021.12.07 [TJOI2013]最长上升子序列(Treap+DP) https://www.luogu.com.cn/problem/P4309 题意: 给定一个序列,初始为空.现在我们将1 ...

  7. 2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS)

    2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS) https://www.luogu.com.cn/problem/P2501 题意: 现在我们有一个长度为 n 的整 ...

  8. 基于Ansible实现Apache Doris快速部署运维指南

    Doris Ansible 使用指南 Apache Doris 介绍 Apache Doris是一个现代化的MPP分析型数据库产品.仅需亚秒级响应时间即可获得查询结果,有效地支持实时数据分析.Apac ...

  9. HCNP Routing&Switching之MUX VLAN

    前文我们了解了代理ARP相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16188230.html:今天我们再来聊一聊vlan隔离相关话题MUX VLA ...

  10. 4.27-Postman和JMeter总结及实战描述

    一.数据格式 常用的请求方法有8种,但是最常用的有4-5种 1.GET 获取资源 2.POST 添加资源(对服务端已存在的资源也可以做修改和删除操作) 3.PUT 修改资源 4 .DELETE删除资源 ...