在流内部分组和替换组,Java 8

问题描述 投票:0回答:2

我有这样的任务:在字符串的排序流中,将3组相同的字符串的所有组更改为包含大写字母的一组(使用Java 8流API)。例如:

input = {"a","a","b","b","b","c"} 

output = {"a","a","B","c"}

我可以在流中计算相同的字符串,但是我不了解如何在没有额外迭代的情况下替换组。我现在所拥有的是:

Map<String, Long> result = Stream.of("a","a","b","b","b","c")
            .collect(Collectors.groupingBy(Function.identity(), 
                    LinkedHashMap::new, Collectors.counting()));

System.out.println(result);

//当前输出:{a = 2,b = 3,c = 1}

java java-8 java-stream grouping collectors
2个回答
0
投票

我可以在流中计数相同的字符串,但我不知道如何替换组,无额外迭代

如果您将继续使用流方法,那么您别无选择,只能流经entrySet()

[我想指出的第二件事是,与其使用counting收集器,不如使用toList收集器会更好,因为当我们通过entrySet执行进一步的操作。

 Stream.of("a", "a", "b", "b", "b", "c")
       .collect(groupingBy(Function.identity(),
                        LinkedHashMap::new,
                        toList()))
       .entrySet().stream()
       .flatMap(e -> e.getValue().size() == 3 ? Stream.of(e.getKey().toUpperCase()) :
             e.getValue().stream())
       .collect(toList());

为了完整起见,如果您要坚持使用counting收集器,则可以执行以下操作:

Stream.of("a", "a", "b", "b", "b", "c")
      .collect(groupingBy(Function.identity(),
                        LinkedHashMap::new,
                        counting()))
      .entrySet().stream()
      .flatMap(e -> e.getValue() == 3 ? Stream.of(e.getKey().toUpperCase()) :
                        Stream.generate(e::getKey).limit(e.getValue()))
      .collect(Collectors.toList());

如果您想...,也可以将Stream.generate(e::getKey).limit(e.getValue())替换为LongStream.range(0, e.getValue()).mapToObj(s -> e.getKey())


0
投票

收集到列表,如果您看到“三元组”,则快退。

List<String> coalesced = Stream.of("a", "a", "b", "b", "b", "c")
  .sequential()
  .collect(LinkedList::new, this::coalesce, List::addAll);
System.out.println(coalesced);

private void coalesce(LinkedList<String> list, String s) {
  if (s.equals(list.peekLast()) &&
      list.size() > 1 &&
      s.equals(list.get(list.size() - 2))) {
    list.removeLast();
    list.removeLast();
    list.add(s.toUpperCase());
  } else {
    list.add(s);
  }
}

作为收集器,这是线程安全的,尽管下面的方法对于单线程流有效,直到List::addAll被意识到“三元组”可以跨越两个列表的事物替换为止。

© www.soinside.com 2019 - 2024. All rights reserved.