使用Java8进行字数统计
我正试图用Java8实现一个字数计算程序,但我无法让它工作。该方法必须将字符串作为参数并返回使用Java8进行字数统计,java,java-8,java-stream,Java,Java 8,Java Stream,我正试图用Java8实现一个字数计算程序,但我无法让它工作。该方法必须将字符串作为参数并返回映射 当我用旧的java方式做这件事时,一切都很好。但是,当我尝试在Java8中执行此操作时,它会返回一个映射,其中键是空的,并且出现的次数正确 以下是我的java 8风格代码: public Map<String, Integer> countJava8(String input){ return Pattern.compile("(\\w+)").splitAsStream(
映射
当我用旧的java方式做这件事时,一切都很好。但是,当我尝试在Java8中执行此操作时,它会返回一个映射,其中键是空的,并且出现的次数正确
以下是我的java 8风格代码:
public Map<String, Integer> countJava8(String input){
return Pattern.compile("(\\w+)").splitAsStream(input).collect(Collectors.groupingBy(e -> e.toLowerCase(), Collectors.reducing(0, e -> 1, Integer::sum)));
}
我认为方法
splitAsStream
会将正则表达式中的匹配元素流化为stream
。我该怎么纠正呢 问题似乎在于,你实际上是在用词分裂,也就是说,你在对所有不是一个词或词与词之间的东西进行分类。不幸的是,似乎没有等效的方法来流式传输实际的匹配结果(很难相信,但我没有找到任何方法;如果你知道的话,请随意评论)
相反,您可以使用\W
而不是\W
按非单词拆分。此外,如注释中所述,您可以使用String::toLowerCase
而不是lambda和Collectors.summingit
使其更具可读性
public static Map<String, Integer> countJava8(String input) {
return Pattern.compile("\\W+")
.splitAsStream(input)
.collect(Collectors.groupingBy(String::toLowerCase,
Collectors.summingInt(s -> 1)));
}
这两种情况的结果似乎是一样的。试试这个
String in = "go go go go og sd";
Map<String, Integer> map = new HashMap<String, Integer>();
//Replace all punctuation with space
String[] s = in.replaceAll("\\p{Punct}", " ").split("\\s+");
for(int i = 0; i < s.length; i++)
{
map.put(s[i], i);
}
Set<String> st = new HashSet<String>(map.keySet());
for(int k = 0; k < s.length; k++)
{
int i = 0;
Pattern p = Pattern.compile(s[k]);
Matcher m = p.matcher(in);
while (m.find()) {
i++;
}
map.put(s[k], i);
}
for(String strin : st)
{
System.out.println("String: " + strin.toString() + " - Occurrency: " + map.get(strin.toString()));
}
System.out.println("Word: " + s.length);
String in=“go og sd”;
Map Map=newhashmap();
//用空格替换所有标点符号
字符串[]s=in.replaceAll(“\\p{Punct},”).split(\\s+”);
对于(int i=0;i
这是输出
字符串:sd,发生率:1
字符串:go,发生率:4
字符串:og,发生率:1
字:6
@大黄蜂金枪鱼编辑不应删除问题的关键部分或修改格式以外的代码。您更改了给定的示例,并删除了该示例的输出以及最后一个问题本身。我已经将问题回滚到它的原始版本。什么是
wordCount.Phrase()
?问题是您将拆分为\w
,因此基本上可以得到所有非单词的内容。。。也可以考虑<代码>。收藏(收藏品。GoopPing(Str::ToLoWrase,Copuls.Cuffing())< /代码>习惯用法(它将返回<代码> map <代码>)。如果你真的需要一个<代码> map <代码>,考虑使用<代码>收藏家。
而不是reduce
.Collectors.counting返回一个Long而不是IntegerYup,模式的JavaDoc说splitAsStream围绕模式的匹配创建流。对我来说,Collectors.counting()
看起来比Collectors.summingit(s->1)更干净
。当然,您必须使用Map
的结果类型,然后…顺便说一句,使用Java 9,您可以这样做,因此您不需要反转模式,尽管生成的代码稍大一些:返回模式。编译(\\w+).matcher(输入)。结果().collector(Collectors.groupingBy(r->r.group().toLowerCase()),Collectors.counting());
最后一句话:getOrDefault
也是一种Java 8方法。因此,如果您想进行旧式计数,但同时使用高级Java 8 API,请使用while(matcher.find())wordcount.merge(matcher.group().toLowerCase(),1,Integer::sum);
这是如何处理标点符号的?您想用标点符号管理字符串吗?我用标点符号编辑代码
{ =7, =1}
{red=1, blue=1, one=1, fish=4, two=1}
public static Map<String, Integer> countJava8(String input) {
return Pattern.compile("\\W+")
.splitAsStream(input)
.collect(Collectors.groupingBy(String::toLowerCase,
Collectors.summingInt(s -> 1)));
}
public static Map<String, Integer> countOldschool(String input) {
Map<String, Integer> wordcount = new HashMap<>();
Matcher matcher = Pattern.compile("\\w+").matcher(input);
while (matcher.find()) {
String word = matcher.group().toLowerCase();
wordcount.put(word, wordcount.getOrDefault(word, 0) + 1);
}
return wordcount;
}
String in = "go go go go og sd";
Map<String, Integer> map = new HashMap<String, Integer>();
//Replace all punctuation with space
String[] s = in.replaceAll("\\p{Punct}", " ").split("\\s+");
for(int i = 0; i < s.length; i++)
{
map.put(s[i], i);
}
Set<String> st = new HashSet<String>(map.keySet());
for(int k = 0; k < s.length; k++)
{
int i = 0;
Pattern p = Pattern.compile(s[k]);
Matcher m = p.matcher(in);
while (m.find()) {
i++;
}
map.put(s[k], i);
}
for(String strin : st)
{
System.out.println("String: " + strin.toString() + " - Occurrency: " + map.get(strin.toString()));
}
System.out.println("Word: " + s.length);