繁体   English   中英

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

[英]Fold operation in Scala Vs Java 8

如何执行下面的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)

这里的输出是

(Char, Int) = (t,6)

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

Stream<Character> sch = tst.chars().mapToObj(i -> (char)i);

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

有人可以帮忙吗?

这样的东西似乎与你提供的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));

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

以下示例使用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));

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

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));

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

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

以下是AbacusUtil中 Stream的示例

String str = "Scala is awesomestttttts";
CharStream.from(str).boxed().groupBy(t -> t, Collectors.counting())
            .max(Comparator.comparing(Map.Entry::getValue)).get();

但我认为Multiset最简单的方法:

CharStream.from(str).toMultiset().maxOccurrences().get();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM