巧用HashMap一行代码统计单词出现次数
简介
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一行代码统计单词出现次数的更多相关文章
- 洛谷 P3804 【模板】后缀自动机 统计单词出现次数
后缀自动机模板题. 关键时求解每个节点的 $right$ 大小. 由于后缀自动机在构建时会保证点和点的 $right$ 只可能没有交集,或者一个是另一个的真子集,我们可以不重复的对 $right$ 进 ...
- 统计单词出现次数的mapreduce
1.新建Java项目 2.导包E:\工具\大数据\大数据提升资料\01-软件资料\06-Hadoop\安装包\Java1.8环境下编译\hadoop-2.7.3\hadoop-2.7.3\share\ ...
- python 统计单词出现次数
#use python3.6 import re from collections import Counter FILESOURCE = './abc.txt' def getMostCommonW ...
- 题目--统计一行文本的单词个数(PTA预习题)
PTA预习题——统计一行文本的单词个数 7-1 统计一行文本的单词个数 (15 分) 本题目要求编写程序统计一行字符中单词的个数.所谓“单词”是指连续不含空格的字符串,各单词之间用空格分隔,空格数可以 ...
- HashMap源码深度剖析,手把手带你分析每一行代码,包会!!!
HashMap源码深度剖析,手把手带你分析每一行代码! 在前面的两篇文章哈希表的原理和200行代码带你写自己的HashMap(如果你阅读这篇文章感觉有点困难,可以先阅读这两篇文章)当中我们仔细谈到了哈 ...
- C# 求精简用一行代码完成的多项判断 重复赋值
C# 求精简用一行代码完成的多项判断 重复赋值 哈哈,说实话,个人看着这么长的三元操作也麻烦,但是我也只想到了这样三元判断句中执行方法体能够写到一行,追求的终极目的是,用一行实现这个过程,而且简单,由 ...
- 洛谷 P1308 统计单词数【字符串+模拟】
P1308 统计单词数 题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定 ...
- spark之scala程序开发(集群运行模式):单词出现次数统计
准备工作: 将运行Scala-Eclipse的机器节点(CloudDeskTop)内存调整至4G,因为需要在该节点上跑本地(local)Spark程序,本地Spark程序会启动Worker进程耗用大量 ...
- 用Hash Table(哈希散列表)实现统计文本每个单词重复次数(频率)
哈希表在查找方面有非常大应用价值,本文记录一下利用哈希散列表来统计文本文件中每个单词出现的重复次数,这个需求当然用NLP技术也很容易实现. 一.基本介绍 1.Hash Key值:将每个单词按照字母组成 ...
随机推荐
- charles抓取HTTPS设置,详细踩坑版
写这篇文章的背景就是,每次我在一台新电脑上用charles抓包时,总是因为各种原因无法抓到https请求,每个百度出来的回答又不是那么详细,需要通过几篇回答才能解决过程中的各种问题,所以把自己的安装经 ...
- 15 张精美动图全面讲解 CORS
前言: 本文翻译自 Lydia Hallie 小姐姐写的
- OpenCL Kernel设计优化
使用Intel® FPGA SDK for OpenCL™ 离线编译器,不需要调整kernel代码便可以将其最佳的适应于固定的硬件设备,而是离线编译器会根据kernel的要求自适应调整硬件的结构. 通 ...
- SpringMvc web.xml配置详情
出处http://blog.csdn.net/u010796790 1.spring 框架解决字符串编码问题:过滤器 CharacterEncodingFilter(filter-name) 2.在w ...
- Docker之Ubuntu上使用Docker的简易教程
Ubuntu上使用Docker的简易教程 原始文档:https://www.yuque.com/lart/linux/fp6cla 说在开头 在天池的比赛中涉及到了docker的使用.经过多番探究,大 ...
- apicloud版人人商城app打包教程
一.APP环境搭建和配置编译1.登录APICLOUD后台新建应用 步骤一 .注册账号注册apicloud 账号并登录APICLOUD控制台 注册apicloud 账号:https://www.apic ...
- Python3.x+Fiddler抓取APP数据
随着移动互联网的市场份额逐步扩大,手机APP已经占据我们的生活,以往的数据分析都借助于爬虫爬取网页数据进行分析,但是新兴的产品有的只有APP,并没有网页端这对于想要提取数据的我们就遇到了些问题,本章以 ...
- 14、Cahin of Responsibility 责任链 COR设计模式
1.责任链模式 chain of responsibility 责任链模式 责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某 ...
- C++中inet_pton、inet_ntop函数
- 头文件windows下:#include <WS2tcpip.h>linux下:#include <sys/socket.h>#include <netinet/in ...
- Flutter 容器(5) - SizedBox
SizedBox: 两种用法:一是可用来设置两个widget之间的间距,二是可以用来限制子组件的大小. import 'package:flutter/material.dart'; class Au ...