简介

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 xml_parser_free() 函数

    定义和用法 xml_parser_free() 函数释放 XML 解析器.高佣联盟 www.cgewang.com 如果成功,该函数则返回 TRUE.如果失败,则返回 FALSE. 语法 xml_pa ...

  2. PHP uniqid() 函数

    实例 生成一个唯一的 ID: <?phpecho uniqid();?>高佣联盟 www.cgewang.com 定义和用法 uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ...

  3. 牛客挑战赛40 VMware和基站 set 二分 启发式合并 区间覆盖

    LINK:VMware和基站 一道 做法并不常见的题目 看起来很难写 其实set维护线段就可以解决了. 容易想到 第二个操作借用启发式合并可以得到一个很不错的复杂度 不过利用线段树维护这个东西 在区间 ...

  4. luogu P6125 [JSOI2009]有趣的游戏

    LINK:有趣的游戏 直接说做法了.首先是 我是不会告诉你我看完题后不太会 摸了2h鱼后看题解 一直翻发现自己题目有些没读完整.. 题目中说了每个字符串长度相同 而我一直在思考AC自动机可能存在一些节 ...

  5. 从别人的代码中学习golang系列--03

    这篇博客还是整理从https://github.com/LyricTian/gin-admin 这个项目中学习的golang相关知识. 作者在项目中使用了 github.com/casbin/casb ...

  6. 【python接口自动化】- ConfigParser配置文件的使用

    前言:目前我们使用的绝大多数计算机程序,无论是办公软件,浏览器,甚至游戏.视频都是通过菜单界面系统配置的,它几乎成了我们使用机器的默认方式.而在python中,也有这样的一个配置模块可以把代码可配置化 ...

  7. Hadoop生态系统入门进阶之一

    组成系统介绍 HDFS:Hadoop 生态圈的基本组成部分是 Hadoop 分布式文件系统(HDFS).HDFS 是一种分布式文件系统,数据被保存在计算机集群上,HDFS 为 HBase 等工具提供了 ...

  8. 牛逼!Python的判断、循环和各种表达式(长文系列第2篇

    流程控制是python语法很重要的一个分支,主要包括我们经常用到的判断语句.循环语句以及各种表达式,这也是上一篇文章没有介绍表达式的原因,在这篇文章中会更加系统全面的讲解这三方面的基础知识. 很多人学 ...

  9. 手把手教你使用Python网络爬虫获取招聘信息

    1.前言 现在在疫情阶段,想找一份不错的工作变得更为困难,很多人会选择去网上看招聘信息.可是招聘信息有一些是错综复杂的.而且不能把全部的信息全部罗列出来,以外卖的58招聘网站来看,资料整理的不清晰. ...

  10. GitLab 数据库

    访问 GitLab 数据库 步骤 用的 Docker Gitlab,首先进入容器 docker exec -it gitlab /bin/bash `` 找到数据库配置文件 ```bash /var/ ...