在Scala Vs Java 8中进行折叠操作

Ana*_*and 5 scala java-8 java-stream

如何执行下面的Scala操作来查找java 8中字符串中最常见的字符?

val tst = "Scala is awesomestttttts"
val op  = tst.foldLeft(Map[Char,Int]())((a,b) => {
    a+(b -> ((a.getOrElse(b, 0))+1))
  }).maxBy(f => f._2)
Run Code Online (Sandbox Code Playgroud)

这里的输出是

(Char, Int) = (t,6)
Run Code Online (Sandbox Code Playgroud)

我能够在Java 8中获得这样的字符流:

Stream<Character> sch = tst.chars().mapToObj(i -> (char)i);
Run Code Online (Sandbox Code Playgroud)

但是无法弄清楚我们在Java 8中使用的fold/foldLeft/foldRight替代方案

有人可以帮忙吗?

JB *_*zet 8

这样的东西似乎与你提供的Scala代码匹配(如果我理解正确的话):

String tst = "Java is awesomestttttts";
Optional<Map.Entry<Character, Long>> max =
    tst.chars()
       .mapToObj(i -> (char) i)
       .collect(Collectors.groupingBy(Function.identity(),
                                      Collectors.counting()))
       .entrySet()
       .stream()
       .max(Comparator.comparing(Map.Entry::getValue));
System.out.println(max.orElse(null));
Run Code Online (Sandbox Code Playgroud)


Don*_*aab 8

如果您不介意使用第三方库,Eclipse Collections有一种Bag可以跟踪字符数的类型.我在下面提供了两个使用Bags的例子.不幸的是,maxByOccurrences今天没有可用Bag,但通过使用topOccurrences(1)可用的结果可以实现相同的结果.您也可以使用forEachWithOccurrences查找最大值,但它会更多一些代码.

以下示例使用a CharAdapter,它也包含在Eclipse Collections中.

MutableBag<Character> characters =
    CharAdapter.adapt("Scala is awesomestttttts")
        .collect(Character::toLowerCase)
        .toBag();
MutableList<ObjectIntPair<Character>> charIntPairs = characters.topOccurrences(2);

Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('t'), 6), charIntPairs.get(0));
Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('s'), 5), charIntPairs.get(1));
Run Code Online (Sandbox Code Playgroud)

第二个示例使用返回的chars()可用方法.有些叫做chars()的东西不会返回CharStream感觉有点尴尬,但这是因为在JDK 8中不可用.StringIntStreamCharStream

MutableBag<Character> characters =
    "Scala is awesomestttttts"
        .toLowerCase()
        .chars()
        .mapToObj(i -> (char) i)
        .collect(Collectors.toCollection(Bags.mutable::empty));
MutableList<ObjectIntPair<Character>> charIntPairs = characters.topOccurrences(2);

Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('t'), 6), charIntPairs.get(0));
Assert.assertEquals(
    PrimitiveTuples.pair(Character.valueOf('s'), 5), charIntPairs.get(1));
Run Code Online (Sandbox Code Playgroud)

在这两个例子中,我首先将字符转换为小写,因此有5次出现's'.如果您希望大写和小写字母不同,则只需删除两个示例中的小写代码.

注意:我是Eclipse Collections的提交者.