简介

JDK是在一直在迭代更新的,很多我们熟悉的类也悄悄的添加了一些新的方法特性。比如我们最常用的HashMap。

今天给大家讲一下HashMap在JDK8中添加的两个新方法compute和merge,从而实现一行代码实现单词统计的功能。一起来看看吧。

爱在JDK8之前

JDK8为我们引入了很多非常非常有用新特性,比如Stream和lambda表达式,可以让我们的程序更加简洁。

如果我们需要统计一个数组中单词出现的次数该怎么做呢?

这里不是讲算法,所以可以直接使用HashMap:

public void countBefore8(){
Map<String,Integer> wordCount= new HashMap<>();
String[] wordArray= new String[]{"we","are","the","world","we"};
for(String word: wordArray){
//如果存在则加1,否则将值设置为1
if(wordCount.containsKey(word)) {
wordCount.put(word, wordCount.get(word) + 1);
}else{
wordCount.put(word, 1);
}
}
}

基本上流程是上面样子的。我们对数组进行遍历,然后判断这个单词是否存在于hashMap中,如果存在则+1。

逻辑很简单,但是看起来有些臃肿。

别怕,我们有JDK8。

JDK8中使用compute

先看下JDK8中compute的定义:

default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key); V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
}

可以看到compute有第二个参数BiFunction,BiFunction就是一个函数,输入两个参数,返回一个参数。

BiFunction的两个参数分别是key和key所对应的oldValue。

可考虑到我们的单词统计,我们可以直接将oldValue+1 即可。所以使用compute,可以将方法改写为:

public void countAfter8WithCompute(){
Map<String,Integer> wordCount= new HashMap<>();
String[] wordArray= new String[]{"we","are","the","world","we"};
Arrays.asList(wordArray).forEach(word ->{
wordCount.putIfAbsent(word,0);
wordCount.compute(word,(w,count)->count+1);
});
}

当然,我们可以将putIfAbsent放到compute中:

public void countAfter8WithCompute2(){
Map<String,Integer> wordCount= new HashMap<>();
String[] wordArray= new String[]{"we","are","the","world","we"};
Arrays.asList(wordArray).forEach(word -> wordCount.compute(word,(w, count)->count == null ? 1 : count + 1));
}

一行代码就完成了。

JDK8中使用merge

再看看merge方法:

default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if (newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}

merge方法需要3个参数,第一个参数是key,第二个参数是key对应的oldValue为空的值,也就是为空的默认值,第三个参数是一个BiFunction参数。

不同的是BiFunction的第一个参数是oldValue,第二个参数是value。

生成newValue的逻辑是:如果oldValue不存在,则使用value。如果oldValue存在,则调用BiFunction对oldValue和Value进行合并。

我们可以写出相应的代码如下:

 public void countAfter8WithMerge(){
Map<String,Integer> wordCount= new HashMap<>();
String[] wordArray= new String[]{"we","are","the","world","we"};
Arrays.asList(wordArray).forEach(word->wordCount.merge(word, 1, (oldCount, one) -> oldCount + one));
}

后面的函数可以用Integer::sum替代:

 public void countAfter8WithMerge(){
Map<String,Integer> wordCount= new HashMap<>();
String[] wordArray= new String[]{"we","are","the","world","we"};
Arrays.asList(wordArray).forEach(word->wordCount.merge(word, 1, Integer::sum));
}

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20/tree/master/java-base

本文已收录于 http://www.flydean.com/wordcount-in-one-line/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

巧用HashMap一行代码统计单词出现次数的更多相关文章

  1. 洛谷 P3804 【模板】后缀自动机 统计单词出现次数

    后缀自动机模板题. 关键时求解每个节点的 $right$ 大小. 由于后缀自动机在构建时会保证点和点的 $right$ 只可能没有交集,或者一个是另一个的真子集,我们可以不重复的对 $right$ 进 ...

  2. 统计单词出现次数的mapreduce

    1.新建Java项目 2.导包E:\工具\大数据\大数据提升资料\01-软件资料\06-Hadoop\安装包\Java1.8环境下编译\hadoop-2.7.3\hadoop-2.7.3\share\ ...

  3. python 统计单词出现次数

    #use python3.6 import re from collections import Counter FILESOURCE = './abc.txt' def getMostCommonW ...

  4. 题目--统计一行文本的单词个数(PTA预习题)

    PTA预习题——统计一行文本的单词个数 7-1 统计一行文本的单词个数 (15 分) 本题目要求编写程序统计一行字符中单词的个数.所谓“单词”是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以 ...

  5. HashMap源码深度剖析,手把手带你分析每一行代码,包会!!!

    HashMap源码深度剖析,手把手带你分析每一行代码! 在前面的两篇文章哈希表的原理和200行代码带你写自己的HashMap(如果你阅读这篇文章感觉有点困难,可以先阅读这两篇文章)当中我们仔细谈到了哈 ...

  6. C# 求精简用一行代码完成的多项判断 重复赋值

    C# 求精简用一行代码完成的多项判断 重复赋值 哈哈,说实话,个人看着这么长的三元操作也麻烦,但是我也只想到了这样三元判断句中执行方法体能够写到一行,追求的终极目的是,用一行实现这个过程,而且简单,由 ...

  7. 洛谷 P1308 统计单词数【字符串+模拟】

    P1308 统计单词数 题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定 ...

  8. spark之scala程序开发(集群运行模式):单词出现次数统计

    准备工作: 将运行Scala-Eclipse的机器节点(CloudDeskTop)内存调整至4G,因为需要在该节点上跑本地(local)Spark程序,本地Spark程序会启动Worker进程耗用大量 ...

  9. 用Hash Table(哈希散列表)实现统计文本每个单词重复次数(频率)

    哈希表在查找方面有非常大应用价值,本文记录一下利用哈希散列表来统计文本文件中每个单词出现的重复次数,这个需求当然用NLP技术也很容易实现. 一.基本介绍 1.Hash Key值:将每个单词按照字母组成 ...

随机推荐

  1. PHP pathinfo() 函数

    定义和用法 pathinfo() 函数以数组的形式返回关于文件路径的信息. 返回的数组元素如下: [dirname]: 目录路径 [basename]: 文件名 [extension]: 文件后缀名 ...

  2. Skill 脚本演示 ycSchReGrid.il

    https://www.cnblogs.com/yeungchie/ ycSchReGrid.il 修复 schematic 或 schematicSymbol 视图中 offGrid 的问题. 回到 ...

  3. SpringCloud生产消费者

    SpringCloud生产消费者 生产者与消费者 上一篇文章介绍了Euarka的搭建,SpringCloud服务注册中心 本篇文章,我们搭建俩个服务,生产者服务与消费者服务. 本文就以电商系统为例:服 ...

  4. 025_go语言中的通道同步

    代码演示 package main import "fmt" import "time" func worker(done chan bool) { fmt.P ...

  5. “随手记”开发记录day07

    今天完成了关于我们页面中的相关信息,由于之前没有做过这个东西,只想着用一个view解决 可是发现我们整的太简单了,还是太年轻,最后想出来要跟java代码一起解决这个问题, 效果

  6. LinuX操作系统基础------> 用户管理,grep搜索

    用户管理 用户组管理 字符管理和grep搜索 1.用户管理: LinuX是一个多用户,多任务的操作系统,可以让多个用户使用,这个账号可以帮助对用户进行追踪,必须在初始化的时候设置好自己的密码 1-1配 ...

  7. react中iconfont如何使用

    一.配置 this.state={ tabs:[ { path:"/home", icon:"\ue628", name:"首页", }, ...

  8. 2020-07-16:如何获得一个链表的倒数第n个元素?

    福哥答案2020-07-16: 1.快慢指针.快指针先走n步,然后快慢指针同时走,直到快指针走到尾.2.两次遍历.第一次遍历获取链表长度,然后计算出序号,然后遍历获取序号下的元素.3.数组保存.遍历一 ...

  9. C#LeetCode刷题之#122-买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4032 访问. 给定一个数组,它的第 i 个元素是一支给定股票第  ...

  10. JDK8 String类知识总结

    一.概述 java的String类可以说是日常实用的最多的类,但是大多数时候都只是简单的拼接或者调用API,今天决定深入点了解一下String类. 要第一时间了解一个类,没有什么比官方的javaDoc ...