使用流嵌套的EnumMap

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

我从Java流开始,在有效的编程书的演讲中,我找到了这段代码:

    public enum Phase {
  SOLID, LIQUID, GAS;

  public enum Transition {
    MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID),
    BOIL(LIQUID, GAS), CONDENSE(GAS, LIQUID),
    SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);

    private final Phase from;
    private final Phase to;

    Transition(Phase from, Phase to) {
        this.from = from;
        this.to = to;
    }
    private static final Map<Phase, Map<Phase, Transition>>
        m = Stream.of(values()).collect(groupingBy(t -> t.from,
            () -> new EnumMap<>(Phase.class),
            toMap(t -> t.to, t -> t,
                (x, y) -> y, () -> new EnumMap<>(Phase.class))));

    public static Transition from(Phase from, Phase to) {
        return m.get(from).get(to);
    }
  }
}

而且我不明白如何创建此EnumMap。对我来说最难理解的是:

toMap(t -> t.to, t -> t,
                (x, y) -> y, () -> new EnumMap<>(Phase.class))));

有人可以向我解释吗?

java stream
2个回答
0
投票

代码的作用:您有一个元素流,并且想要按初始阶段将它们分组。在这里,作者选择使用复杂的分组操作,这将对分组数据进行后转换。这是toMap函数的用处。groupingBy收集器开始缓冲元素后,它将委派给mapTo收集器以为每个组建立自定义记录。在这里,作者使用toMap通过其[[target状态:[[to。]]为阶段建立索引。所以,让我们分解它:Stream.of(values()) // Queries a result .collect( // Elements must be grouped using a key, extracted from each streamed value groupingBy( // Specify how to extract the grouping key t -> t.from, // Here, the author specifies himself how to create the group map, // to be sure it will use a custom enum-optimized key management. () -> new EnumMap<>(Phase.class), // Nest another collector, to transform the list of values // of each group into something else. Note that toMap does not // buffer a collection of values for a key. It is designed to // map a key to each value. But, it allows user to merge // merge conflicting values if needed. toMap( // Same than groupby, we specify how to extract key from value. t -> t.to, // Here, specify that the value associated to the key is the // object we've extracted key from. Here, wwe could have changed // it to something else (a text representation, for example). t -> t, // toMap will bind one key to one value. We have to solve // conflict ourself. Here, author decided to drop arbitrarily // one of the values. (x, y) -> y, // As for groupby operator, author forces a map implementation // dedicated to enum keys. () -> new EnumMap<>(Phase.class))));

最后,官方stream collection documentation提供了一些解释。

我不确定我的解释是否足够,您可以在评论中发表评论。

这里正在创建的是一种Maps地图,当从一种状态转到另一种状态时,它提供了Transition方法。如果完成时没有lambda或流,则可能如下所示:


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.