Java 8 Streams - Collectors.toMap 例子

4,784 阅读2分钟

 function.Collectors.toMap() 有三个重载方法:

<T,K,U> Collector<T,?,Map<K,U>> toMap(
                                  Function<? super T,? extends K> keyMapper,
                                  Function<? super T,? extends U> valueMapper)

<T,K,U> Collector<T,?,Map<K,U>> toMap(
                                  Function<? super T,? extends K> keyMapper,
                                  Function<? super T,? extends U> valueMapper,
                                  BinaryOperator<U> mergeFunction)

<T,K,U,M extends Map<K,U>> Collector<T,?,M> toMap(
                                  Function<? super T,? extends K> keyMapper,
                                  Function<? super T,? extends U> valueMapper,
                                  BinaryOperator<U> mergeFunction,
                                  Supplier<M> mapSupplier)


  Parameters 

  • keyMapper: 为新的map产生新的key 的方法
  • valueMapper: 为新的map 产生新的value的方法
  • mergeFunction: 解决重复键冲突的二进制operator方法 ,输入参数是有同一个key的值们
  • mapSupplier:   自定义生成的Map下的实现类


例子:

1,

package com.logicbig.example.collectors;

import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ToMapExample {
    public static void main (String[] args) {
        Stream<String> s = Stream.of("apple", "banana", "orange");
        Map<Character, String> m = s.collect(
                            Collectors.toMap(s1 -> s1.charAt(0),
                                                s1 -> s1));
        System.out.println(m);
    }
} 

输出:

{a=apple, b=banana, o=orange}


2,  当 keyMapper 方法 中有重复的键存在,   Collectors.toMap(keyMapper, valueMapper) 会 throw IllegalStateException

package com.logicbig.example.collectors;

import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ToMapExample1 {
    public static void main (String[] args) {
        Stream<String> s = Stream.of("apple", "banana", "apricot", "orange");
        Map<Character, String> m = s.collect(
                            Collectors.toMap(s1 -> s1.charAt(0),
                                                s1 -> s1));
        System.out.println(m);
    }
} 

输出

Caused by: java.lang.IllegalStateException: Duplicate key apple
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1253)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.logicbig.example.collectors.ToMapExample1.main(ToMapExample1.java:17)
	... 6 more 


3,所以要加一个处理方法、即第三个参数

package com.logicbig.example.collectors;

import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ToMapExample2 {
    public static void main (String[] args) {
        Stream<String> s = Stream.of("apple", "banana", "apricot", "orange",
                            "apple");
        Map<Character, String> m = s.collect(
                            Collectors.toMap(s1 -> s1.charAt(0),
                                                s1 -> s1,
                                                (s1, s2) -> s1 + "|" + s2));
        System.out.println(m);
    }
} 

输出:

{a=apple|apricot|apple, b=banana, o=orange}

4, 第四个参数默认输出hashmap 结果是为无序  指定 LinkedHashMap 是有序的

package com.logicbig.example.collectors;

import java.util.LinkedHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ToMapExample3 {
    public static void main (String[] args) {
        Stream<String> s = Stream.of("apple", "banana", "apricot", "orange",
                            "apple");
        LinkedHashMap<Character, String> m = s.collect(
                            Collectors.toMap(s1 -> s1.charAt(0),
                                                s1 -> s1,
                                                (s1, s2) -> s1 + "|" + s2,
                                                LinkedHashMap::new));
        System.out.println(m);
    }
} 

输出:

{a=apple|apricot|apple, b=banana, o=orange}