以下为 Jean 学习笔记和习题整理,供学习和参考

# String

String 底层就是 char [],char 类型的数组,使用时开发者不需要直接操作底层数组,用更加简便的方式即可完成对字符串的使用。

特点:

  • 不变性:对 String 对象进行任何操作都是创建一个新的对象,再把引用指向该对象。不变的模式主要作用在当一个对象需要被多线程共享并频繁访问时,可以保持数据的一致性。

  • 常量池优化:String 创建对象之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。

  • final: 使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。这也是 String 为什么不可变

    源码:private final char value [];

❓String 真的不可变的吗?

1.String 不可变但不代表引用不可以变;

2. 通过反射是可以修改所谓的 “不可变” 对象。

String s = "hello world";
System.out.println("s=" + s); // s=hello world
// 获取 String 类中的 value 字段
Filed valueFieldOfString = String.class.getDeclarField("value");
// 改变 value 属性的访问权限
valueFiledOfString.setAccessible(true);
// 获取 s 对象上的 value 的属性
char[] value =char[])valueFiledOfString.get(s);
// 改变
value[5] = '_';
System.out.println("s=" + s); // s=hello_world

和 Integer 一样,String str = "i"; 和 String str = new String ("i"); 不一样,前者被 JVM 分配到常量池中,而 new 出来的对象都在堆内存中。

String 的常用方法:

  • indexOf (): 返回指定字符的索引
  • charAt (): 返回指定索引处的字符
  • replace (): 替换
  • trim (): 去除两端空白
  • split (): 分割字符串的 byte 类型的数组;
  • length (): 返回字符串的长度
  • toLowerCase (): 小写 -> 大写
  • toUpperCase (): 大写 -> 小写
  • substring (): 截取
  • equals (); 比较

# StringBuffer

上面说了 String 的源码里面,private final char value [];, 所以 String 对象是不可变的,而 StringBuilder 和 StringBuffer 都是继承自 AbstractBuilder 类,在 AbstractBuilder 中也是使用字符数组保存字符串,char [] value, 这两种对象都是可变的,String 中的对象都是不可变的,可以理解为常量,线程安全。

StringBuffer 对方法加了同步锁或者对调用方法加了同步锁,所以线程是安全的,StringBuffer 每次都会对 StringBuffer 对象本身操作。

# StringBuilder

线程不安全,性能比 StringBuffer 获得了 10%-15% 提升。

性能:String<StringBuffer<StringBuilder

# 问题:

# 1.HashMap 用 String 作为 key 有什么好处?

HashMap 内部通过 key 的 hashcode 来确定 value 的存储位置,因为字符串不可变的,所以创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,相对于其他对象更快;

更新于

请我喝[茶]~( ̄▽ ̄)~*

Jean 微信支付

微信支付

Jean 支付宝

支付宝

Jean 贝宝

贝宝