1.9 收集到映射表中
假设我们有一个Stream,并且想要将其元素收集到一个映射表中,这样后续就可以通过它们的ID来查找人员了。Collectors.toMap方法有两个函数引元,它们用来产生映射表的键和值。例如,
如果有多个元素具有相同的键,那么就会存在冲突,收集器将会抛出一个Illegal-StateException对象。可以通过提供第3个函数引元来覆盖这种行为,该函数会针对给定的已有值和新值来解决冲突并确定键对应的值。这个函数应该返回已有值、新值或它们的组合。
在下面的代码中,我们构建了一个映射表,存储了所有可用Locale中的每种语言,它在默认Locale中的名字(例如“German”)为键,而其本地化的名字(例如“Deutsch”)为值:
我们不关心同一种语言是否可能会出现2次(例如,德国和瑞士都使用德语),因此我们只记录第一项。
注意:在本章中,我们使用Locale类作为感兴趣的数据集的数据源。请参阅第7章以了解有关Locale的更多信息。
现在,假设我们想要了解给定国家的所有语言,这样我们就需要一个Map>。例如,“Switzerland”的值是集[French, German, Italian]。首先,我们为每种语言都存储一个单例集。无论何时,只要找到了给定国家的新语言,我们都会将已有集和新集做并操作。
在下一节中,你将会看到一种更简单的用于获取这种映射表的方式。
如果想要得到TreeMap,那么可以将构造器作为第4个引元来提供。你必须提供一种合并函数。下面是本节一开始所列举的示例之一,现在它会产生一个TreeMap:
注意:对于每一个toMap方法,都有一个等价的可以产生并发映射表的toConcurrentMap方法。单个并发映射表可以用于并行集合处理。当使用并行流时,共享的映射表比合并映射表要更高效。注意,元素不再是按照流中的顺序收集的,但是通常这不会有什么问题。
程序清单1-5中的示例程序给出了将流的结果收集到映射表中的示例。
程序清单1-5 collectin/CollectingIntoMaps.java
java.util.stream.Collector 8
产生一个收集器,它会产生一个映射表或并发映射表。keyMapper和valueMapper函数会应用于每个收集到的元素上,从而在所产生的映射表中生成一个键/值项。默认情况下,当两个元素产生相同的键时,会抛出一个IllegalStateException异常。你可以提供一个mergeFunction来合并具有相同键的值。默认情况下,其结果是一个HashMap或ConcurrentHashMap。你可以提供一个mapSupplier ,它会产生所期望的映射表实例。