我想找到一种简单的方法来用Java 8流式传输Map 。猜猜是什么? 没有!
 为了方便起见,我期望的是以下方法: 
public interface Map<K, V> {default Stream<Entry<K, V>> stream() {return entrySet().stream();}    
}但是没有这种方法。 不应使用这种方法的原因可能多种多样,例如:
-  没有选择keySet()或values()作为流源的entrySet()“明确”首选项
-  Map并不是真正的收藏。 它甚至都不是可Iterable
- 那不是设计目标
- EG没有足够的时间
 好吧,对于Map进行改型以提供entrySet().stream()并最终实现Iterable<Entry<K, V>> ,这是一个非常令人信服的理由。 那就是我们现在有了Map.forEach()的事实: 
default void forEach(BiConsumer<? super K, ? super V> action) {Objects.requireNonNull(action);for (Map.Entry<K, V> entry : entrySet()) {K k;V v;try {k = entry.getKey();v = entry.getValue();} catch(IllegalStateException ise) {// this usually means the entry is no longer in the map.throw new ConcurrentModificationException(ise);}action.accept(k, v);}
} 在这种情况下, forEach()接受BiConsumer ,该BiConsumer实际上消耗了映射中的条目。 如果您搜索JDK源代码,则Map.forEach()之外的BiConsumer类型的引用实际上很少,也许还有几个CompletableFuture方法和几个流收集方法。 
 因此,几乎可以假定BiConsumer受到此forEach()方法的强烈驱动,这对于使Map.Entry在整个collection API中成为更重要的类型是一个很好的情况(我们更倾向于使用Tuple2类型,课程)。 
 让我们继续这种思路。 还有Iterable.forEach() : 
public interface Iterable<T> {default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}}
} 尽管有细微的差别,但Map.forEach()和Iterable.forEach()直观地迭代了各自收集模型的“条目”。 
-  Iterable.forEach()期望Consumer获得单个值
-  Map.forEach()期望BiConsumer两个值:键和值( 不是Map.Entry!)
这样考虑:
这使得这两种方法在“鸭子键入意义上”不兼容,这使得这两种类型更加不同
mm!
用jOOλ改善地图
 我们发现这很古怪且违反直觉。 实际上, forEach()并不是Map遍历和转换的唯一用例。 我们希望有一个Stream<Entry<K, V>>甚至更好的是Stream<Tuple2<T1, T2>> 。 因此,我们在jOOλ中实现了该功能 ,这是我们为jOOQ的集成测试开发的库。 使用jOOλ,您现在可以将Map封装为Seq类型(“ Seq”表示顺序流,即具有更多功能特征的流): 
Map<Integer, String> map = new LinkedHashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");assertEquals(Arrays.asList(tuple(1, "a"), tuple(2, "b"), tuple(3, "c")),Seq.seq(map).toList()
); 你能用它做什么? 如何创建一个新的Map ,一次性交换键和值: 
System.out.println(Seq.seq(map).map(Tuple2::swap).toMap(Tuple2::v1, Tuple2::v2)
);System.out.println(Seq.seq(map).toMap(Tuple2::v2, Tuple2::v1)
);以上两种都会产生:
{a=1, b=2, c=3}仅作记录,以下是使用标准JDK API交换键和值的方法:
System.out.println(map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey))
);可以做到,但是每天标准Java API的冗长性使事情变得很难读/写。
翻译自: https://www.javacodegeeks.com/2014/10/lets-stream-a-map-in-java-8-with-jooλ.html