
原来你是这样的JAVA[05]--String
发布日期:2021-05-19 02:38:02
浏览次数:20
分类:博客文章
本文共 4493 字,大约阅读时间需要 14 分钟。
1.从概念上讲,java字符串就是Unicode字符串。
2.字符串拼接用指定分隔符拼接字符串数组时,使用StringJoiner或者String.join()更方便;用StringJoiner拼接字符串时,还可以额外附加一个“开头”和“结尾”。@Test public void join1() { String[] names = {"Bob", "Alice", "Grace"}; StringJoiner sj = new StringJoiner(", ", "Hello ", "!"); for (String name : names) { sj.add(name); } System.out.println(sj.toString()); } @Test public void join2() { String[] names = {"Bob", "Alice", "Grace"}; String s = String.join(", ", names); System.out.println(s); }
3.子串substring
String类的substring方法可以从一个较大的字符串提取出一个子串,public static void main(String[] args) { //子串 String s = "你好,今天是2017年12月24日,圣诞快乐!!"; String date = s.substring(6, 17); System.out.println(date);//输出:2017年12月24日 }
查看String源码,substring(beginIndex,endIndex):返回子字符串,从beginIndex到endIndex-1,通过调用String构造方法创建了一个新的String对象。
public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > value.length) { throw new StringIndexOutOfBoundsException(endIndex); } int subLen = endIndex - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); } private final char value[];public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= value.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); }
4.字符串判等equals
当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。所以一定不要使用运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放置在同一个位置上。如果虚拟机始终将相同的字符串共享,就可以使用运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。另外,使用equals方法时要注意避免NP。public static void main(String[] args) { //判等 String s3 = "abc"; String s4 = "abc"; String s5 = new String("abc"); String s6 = new String("abc"); System.out.println(s3 == s4);//true System.out.println(s3.equals(s4));//true System.out.println(s5 == s6);//false System.out.println(s5.equals(s6));//true //避免NP String s7 = null;// System.out.println(s7.equals("null"));//NP System.out.println(s7 != null && s7.equals("null")); System.out.println("null".equals(s7)); }
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { 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; }
5.String,StringBuilder和StringBuffer
①String字符串为什么是不可变的?
简单的来说:String 类中使用 final 关键字修饰字符数组来保存字符串,所以 String 对象是不可变的。
低版本实现:private final char value[];
Java9之后的版本:
private final byte[] value;
而 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串byte[] value, 没有用 final 关键字修饰,所以这两种对象都是可变的。
②线程安全性
String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些字符串的基本操作。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。@Override @HotSpotIntrinsicCandidate public StringBuilder append(String str) { super.append(str); return this; } @Override @HotSpotIntrinsicCandidate public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
③对于三者使用的总结:
- 少量操作字符串用 String
- 单线程操作字符串缓冲区下大量数据用 StringBuilder
- 多线程操作字符串缓冲区下大量数据用 StringBuffer
发表评论
最新留言
关注你微信了!
[***.104.42.241]2025年05月10日 07时09分37秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
使用ivx图表组件的经验总结
2019-03-21
17场演讲,500+嘉宾 |「观远2020智能决策峰会暨产品发布会」看点先知道
2019-03-21
专访汇付数据副总裁姜靖宇:“纸上谈兵”时代终结,人工智能将变革第三方支付行业
2019-03-21
张小龙的“败走麦城”
2019-03-21
小程序的生命周期
2019-03-21
Redis学习笔记—单个键管理
2019-03-21
多线程基础部分
2019-03-21
Java学习记录之ArrayList集合
2019-03-21
PHP之配置开发环境
2019-03-21
Shiro 的身份认证
2019-03-21
什么是信道编码?信道编码比较
2019-03-21
wordpress架站踩坑过程
2019-03-21
一个简单的游戏框架[汇总]
2019-03-21
NSNotification、delegate和KVO的区别
2019-03-21
Rhino简介
2019-03-21
防止用户重复提交表单的处理方法
2019-03-21
JS代码执行顺序
2019-03-21
免费好用的证件扫描仪-扫描全能王
2019-03-21
自定义拦截器
2019-03-21
自定义拦截器
2019-03-21