乐趣区

关于java:别再这么写代码了这几个方法不香吗

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 有一个益处,针对传入 Mapnull 的状况,能够设置默认值。

假如咱们是从 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) {

如果 Mapkey 对应的 value 不存在,则会将 mappingFunction 计算产生的值作为保留为该 keyvalue,并且返回该值。否则不作任何计算,将会间接返回 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");

那其实这是谬误的,当 Mapkey 对应 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。

那如果 javacountMap 中存在,则会调用第三个参数 remappingFunction 函数办法进行计算。

remappingFunction 函数中,oldValue代表原先 countMapjava 的值,newValue代表咱们设置第二个参数 1,这里咱们将两者相加,刚好实现累加的需要。

最初

这次次要从集体日常碰到三个场景登程,给大家比照了一下应用 JDK8 Map 新增办法只会,两者代码区别。

从下面能够很显著看出,应用新增办法之后,咱们能够用很少的代码能够实现,整体看起来变得十分简洁。

不过 JDK8 之后很多办法都会用到 lambda 函数,不相熟的话,其实比拟难以了解代码。

不过也还好,咱们只有在日常编码过程中,刻意去练习应用,很快就能上手。

最初,JDK8 还有许多好用办法,刻意简化代码开发,你能够在留言区举荐几个吗?

欢送关注我的公众号:小黑十一点半,取得日常干货推送。如果您对我的专题内容感兴趣,也能够关注我的博客:studyidea.cn

退出移动版