共计 3867 个字符,预计需要花费 10 分钟才能阅读完成。
JDK8 应该是 Java 中最坚挺一个版本,这个版本新增很多个性,让咱们开发起来多了很多便当。
不过最近 Review 我的项目代码的时候发现,尽管很多我的项目工程曾经应用了 JDK8,然而工程代码却很少应用到 JDK8 新个性、新办法。
如果单从代码正确性上来说,老形式写法写当然没有什么问题,那惟一的毛病其实就是代码行数比拟多,比拟繁琐。
那同样的需要,应用 JDK8 新办法,其实几行代码就能够搞定,这样代码就会变得十分简洁。
明天就以三个比拟常见的场景为例,教你几招,应用 JDK8 Map
新增的办法简化代码开发。
上面就来看看这次行将用到 Map
几个新办法:
欢送关注我的公众号:小黑十一点半,取得日常干货推送。如果您对我的专题内容感兴趣,也能够关注我的博客:studyidea.cn
预防空指针问题
日常开发中咱们通常会从 Map
获取元素,而后进行相干的业务解决,示例代码如下:
Map<String, String> map = new HashMap();
map.put("公号", "小黑十一点半");
map.put("主理人", "楼下小黑哥");
// 可能存在 NPE 问题
System.out.println(map.get("领取").toUpperCase());
如果就像示例代码间接解决,一旦 Map
中相应元素不存在,那么咱们就会碰到空指针问题。
为了解决这个问题,通常咱们能够先判断一下元素是否为 null
,如果不为 null
,再做相应的业务解决。
// 第一种 if 判空
String value = map.get("领取");
if (!Objects.isNull(value)) {System.out.println(value.toUpperCase());
}
这种形式惟一劣势就是代码解决上比拟繁琐,不是很简洁。
所以针对这种状况,其实能够应用 条件运算符,设置一个默认空值,从而防止后续解决产生空指针。
// 第一种 if 判空
String value = map.get("领取");
// 第二种 条件运算符
value = Objects.isNull(value) ? "" : value;
这种形式比拟简洁,所以日常开发中我比拟喜爱用这种形式。
ps: 这里的前提,空字符串对于业务没有非凡意义。如果存在非凡意义,那就不能应用这种形式了。
那如果应用 JDK8,其实就很不便了,咱们就能够应用 Map#getOrDefault
间接代替条件运算符。
// 等同于条件运算符的成果:Objects.isNull(value) ? "" : value;
String value = map.getOrDefault("领取","");
借助 Map#getOrDefault
一行代码间接搞定,就是这么简略。
如果你还在应用 JDK8 之前的版本,没方法应用这个办法。没关系,咱们能够借助 Apache Common-Lang3 提供的工具类 MapUtils
防止空指针。
// Apache MapUtils
String value = MapUtils.getString(map, "领取", "");
MapUtils
这个工具类绝对于 Map#getOrDefault
有一个益处,针对传入 Map
为 null
的状况,能够设置默认值。
假如咱们是从 POJO
对象获取 Map
参数,这个时候为了避免空指针,咱们就须要提前做一个空指针的判断。
不过如果应用 MapUtils
,那咱们就不须要判断是否为 null
,办法外部曾经封装这个逻辑。
MapUtils.getString(pojo.getMap(),"领取", "");
巧用 computeIfAbsent
日常开发中,咱们会碰到这类场景,须要一个键须要映射到多个值,这个时候咱们能够应用 Map<K, List<V>>
这个构造。
此时增加元素的时候,咱们须要做一些判断,当外部元素不存在时候被动创立一个汇合对象,示例代码如下:
Map<String, List<String>> map = new HashMap();
List<String> classify = map.get("java 框架");
if (Objects.isNull(classify)) {classify = new ArrayList<>();
classify.add("Spring");
map.put("java 框架", classify);
} else {classify.add("Spring");
}
下面的代码比拟繁琐,到了 JDK8,Map
新增一个 computeIfAbsent
办法:
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
如果 Map
中 key
对应的 value
不存在,则会将 mappingFunction
计算产生的值作为保留为该 key
的 value
,并且返回该值。否则不作任何计算,将会间接返回 key
对应的 value。
利用这个个性,咱们能够间接应用 Map#computeIfAbsent
一行代码实现下面的场景,示例代码如下:
map.computeIfAbsent("java 框架", key -> new ArrayList<>()).add("Spring");
那其实 Map
中还有一个办法 putIfAbsent
,性能跟 computeIfAbsent
比拟相似。
那刚开始应用的时候,误以为能够应用 putIfAbsent
实现下面的需要:
// ERROR: 会有 NPE 问题
map.putIfAbsent("java 框架", new ArrayList<>()).add("Spring");
那其实这是谬误的,当 Map
中 key
对应 value
不存在的时候,putIfAbsent
将会间接返回 null
。
而 computeIfAbsent
将会返回 mappingFunction
计算之后的值,像下面的场景间接返回就是 new ArrayList
。
这一点须要留神一下,切勿用错办法,导致空指针。
最初针对下面这种一个键须要映射到多个值,其实还有一个更优良的解决办法,应用 Google Guava 提供的新汇合类型 Multiset
,以此疾速实现一个键须要映射到多个值的场景。
示例代码如下:
ArrayListMultimap<Object, Object> multiset= ArrayListMultimap.create();
multiset.put("java 框架","Spring");
multiset.put("java 框架","Mybatis");
// java 框架 --->Spring,Mybatis
单词统计
假如有如下需要,咱们须要统计一段文字中相干单词呈现的次数。那实现形式其实很简略,应用 Map
存储相干单词的次数即可,示例代码如下:
Map<String, Integer> countMap = new HashMap();
Integer count = countMap.get("java");
if (Objects.isNull(count)) {countMap.put("java", 1);
} else {countMap.put("java", count++);
}
这类代码是不是很相熟?同样比拟繁琐。
接下来咱们能够应用 JDK8 Map
新增办法进行革新,这次应用下面用过的 getOrDefault
再加 put
办法疾速解决,示例代码如下:
// getOrDefault
Integer count = countMap.getOrDefault("java",0);
countMap.put("java", count + 1);
那其实咱们还有一种方法,这次咱们应用 Map#merge
这个新办法,一句代码实现上述需要,示例代码如下:
countMap.merge("java", 1, Integer::sum);
说真的,刚看到 merge
这个办法的时候还是有点懵,尤其前面间接应用 lambda
函数,让人不是很好了解。
这里先将lambda
函数还原成失常类,给大家着重解释一下这个办法:
countMap.merge("java", 1, new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer oldValue, Integer newValue) {return Integer.sum(oldValue,newValue);
}
});
用下面代码阐明一下 merge
办法,如果 java
这个值在 countMap
中不存在,那么将会其对应的 value
设置为 1。
那如果 java
在 countMap
中存在,则会调用第三个参数 remappingFunction
函数办法进行计算。
remappingFunction
函数中,oldValue
代表原先 countMap
中 java
的值,newValue
代表咱们设置第二个参数 1,这里咱们将两者相加,刚好实现累加的需要。
最初
这次次要从集体日常碰到三个场景登程,给大家比照了一下应用 JDK8 Map
新增办法只会,两者代码区别。
从下面能够很显著看出,应用新增办法之后,咱们能够用很少的代码能够实现,整体看起来变得十分简洁。
不过 JDK8 之后很多办法都会用到 lambda
函数,不相熟的话,其实比拟难以了解代码。
不过也还好,咱们只有在日常编码过程中,刻意去练习应用,很快就能上手。
最初,JDK8 还有许多好用办法,刻意简化代码开发,你能够在留言区举荐几个吗?
欢送关注我的公众号:小黑十一点半,取得日常干货推送。如果您对我的专题内容感兴趣,也能够关注我的博客:studyidea.cn