您好,欢迎来到九壹网。
搜索
您的当前位置:首页Java8源码解析-String、Long

Java8源码解析-String、Long

来源:九壹网
Java8源码解析-String、Long

String

不变性

代码demo:

String s =\"hello\";s =\"world\";

从代码表⾯看,s 的值好像被修改了,但从 debug 的⽇志来看,其实是 s 的内存地址被修改了,也就是说 s =\"world\" 这⼀⾏看似简单的赋值,其实已经把 s 的引⽤指向了新的 String。

String源码:

public final class String

implements java.io.Serializable, Comparable, CharSequence { /** The value is used for character storage. */ private final char value[];}

1. String 类被 final 修饰,说明 String 类绝不可能被继承了,也就是说任何对 String 的操作⽅法,都不会被继承覆写;

2. String 中保存数据的是⼀个 char 的数组 value。 value 也是被 final 修饰的,也就是说 value ⼀旦被赋值,内存地址是绝对⽆法修改的,⽽且 value 的权限是 private 的,外部绝对访问不到,String 也没有开放出可以对 value 进⾏赋值的⽅法,所以说 value ⼀旦产⽣,内存地址就根本⽆法被修改。

因为String 的⼤多数操作⽅法,都会返回新的 String,所以以下写法是不对的。

String str =\"hello world !!\";

// 这种写法是替换不掉的,必须接受 replace ⽅法返回的参数才⾏,这样才⾏:str = str.replace(\"l\str.replace(\"l\

substring

类属性的⾸字母转化为⼩写⼀般使⽤substring截取字符串如下:

name.substring(0, 1).toLowerCase() + name.substring(1);

substring有两个⽅法

1. public String substring(int beginIndex, int endIndex)

beginIndex:开始位置,endIndex:结束位置;2. public String substring(int beginIndex)

beginIndex:开始位置,结束位置为⽂本末尾。

substring的⽅法底层是使⽤的字符数组范围截取的⽅法:Arrays.copyOfRange(字符数组, 开始位置, 结束位置);从字符数组中进⾏⼀段范围的拷贝。

equals

判断相等有equals 和 equalsIgnoreCase,后者判断相等时,会忽略⼤⼩写equals源码:

public boolean equals(Object anObject) { // 判断内存地址是否相同 if (this == anObject) { return true; }

// 待⽐较的对象是否是 String,如果不是 String,直接返回不相等

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;}

replace

replace 替换所有字符、replaceAll 批量替换字符串、replaceFirst 替换遇到的第⼀个字符串

replace 有两个⽅法,⼀个⼊参是 char,⼀个⼊参是 String,前者表⽰替换所有字符,如:name.replace('a','b'),后者表⽰替换所有字符串,如:name.replace(\"a\

split

demo代码;

String s =\"boo:and:foo\";

// 对 s 进⾏了各种拆分,演⽰的代码和结果是:s.split(\":\") 结果:[\"boo\s.split(\":\结果:[\"boo\s.split(\":\结果:[\"boo\s.split(\":\结果:[\"boo\s.split(\"o\") 结果:[\"b\s.split(\"o\结果:[\"b\

若有空值

String a =\

a.split(\结果:[\"\

空值是拆分不掉的,仍然成为结果数组的⼀员,若想删除空值,只能⾃⼰拿到结果后再做操作,但 Guava(Google 开源的技术⼯具) 提供了⼀些可靠的⼯具类,可以帮助快速去掉空值,如下:

String a =\

// Splitter 是 Guava 提供的 API List list = Splitter.on(',') .trimResults()// 去掉空格

.omitEmptyStrings()// 去掉空值 .splitToList(a);

log.info(\"Guava 去掉空格的分割⽅法:{}\// 打印出的结果为:[\"a\

join

join⽅法是静态的,可以直接使⽤。⽅法有两个⼊参,参数⼀是合并的分隔符,参数⼆是合并的数据源,数据源⽀持数组和 List,在使⽤的时候,有两个不太⽅便的地⽅:

1. 不⽀持依次 join 多个字符串,⽐如想依次 join 字符串 s 和 s1,如果这么写的话 String.join(\ 最后得到的是 s1 的值,第⼀次join 的值被第⼆次 join 覆盖了;

2. 如果 join 的是⼀个 List,⽆法⾃动过滤掉 null 值。Guava 正好提供了 API

// 依次 join 多个字符串,Joiner 是 Guava 提供的 API

Joiner joiner = Joiner.on(\

String result = joiner.join(\"hello\log.info(\"依次 join 多个字符串:{}\

List list = Lists.newArrayList(new String[]{\"hello\log.info(\"⾃动删除 list 中空值:{}\// 输出的结果为;

依次 join 多个字符串:hello,china⾃动删除 list 中空值:hello,china

Long

Long ⾃⼰实现了⼀种缓存机制,缓存了从 -128 到 127 内的所有 Long 值,如果是这个范围内的 Long 值,就不会初始化,⽽是从缓存中拿,缓存初始化源码如下:

private static class LongCache { private LongCache(){}

// 缓存,范围从 -128 到 127,+1 是因为有个 0

static final Long cache[] = new Long[-(-128) + 127 + 1];

// 容器初始化时,进⾏加载 static {

// 缓存 Long 值,注意这⾥是 i - 128 ,所以再拿的时候就需要 + 128 for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); }}

使⽤ Long 时,推荐多使⽤ valueOf ⽅法,少使⽤ parseLong ⽅法。因为 Long 本⾝缓存了 -128 到 127 范围内的 Long,valueOf ⽅法会从缓存中去拿值,如果命中缓存,会减少资源的开销,parseLong ⽅法就没有这个机制。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务