我创建了计算字母表中每个字符的方法。我是学习流(函数式编程)并尝试尽可能多地使用它们,但在这种情况下我不知道如何做到这一点:
.gallery
那么,如何使用Java 8流重写它?
答案 0 :(得分:36)
避免使用其他答案中提供的基于AtomicInteger
的解决方案等有状态索引计数器。如果流是并行的,它们将失败。相反,流式传输索引:
IntStream.range(0, alphabet.size())
.boxed()
.collect(toMap(alphabet::get, i -> i));
上面假设传入列表不应该有重复的字符,因为它是一个字母表。如果您有可能重复元素,那么多个元素将映射到相同的键,然后您需要指定merge function。例如,您可以使用(a,b) -> b
或(a,b) ->a
作为toMap
方法的第三个参数。
答案 1 :(得分:12)
最好使用Function.identity()
代替i->i
:
IntStream.range(0, alphabet.size())
.boxed()
.collect(toMap(alphabet::get, Function.identity()));
答案 2 :(得分:6)
在Java 8中使用带AtomicInteger
的流:
private Map<Character, Integer> numerateAlphabet(List<Character> alphabet) {
AtomicInteger index = new AtomicInteger();
return alphabet.stream().collect(
Collectors.toMap(s -> s, s -> index.getAndIncrement(), (oldV, newV)->newV));
}
答案 3 :(得分:1)
使用AtomicInteger
AtomicInteger counter = new AtomicInteger();
Map<Character, Integer> map = characters.stream()
.collect(Collectors.toMap((c) -> c, (c) -> counter.incrementAndGet()));
System.out.println(map);
答案 4 :(得分:1)
您可以将流收集到地图并将地图大小用作索引。
alphabet.stream()
.collect(HashMap::new, (map, ch) -> map.put(ch, map.size()), Map::putAll);
答案 5 :(得分:0)
如果你在 Map 中有重复的值,你可以这样做
Map<Object, Deque<Integer>> result = IntStream.range(0, source.size()).boxed()
.collect(Collectors.groupingBy(source::get, Collectors.toList()));
或者如果您需要特定的 Map/List 实现,则像这样:
Map<Object, Deque<Integer>> result = IntStream.range(0, source.size()).boxed()
.collect(Collectors.groupingBy(source::get, IdentityHashMap::new, Collectors.toCollection(ArrayDeque::new)));