Java 8 List转Map(解决key重复报异常)

package com.demo.jdk8.collectors;

import com.demo.jdk8.collectors.model.User;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/** * throw new IllegalStateException(String.format("Duplicate key %s", u)); * 解决方法:调用三个参数的toMap重载方法,第三个参数为:BinaryOperator<U> mergeFunction * * @author Shanks * @date 2018-10-10 */
public class ToMapTest {

    private static User user = new User(1, "Tom");
    private static User user1 = new User(2, "Jerry");
    private static User user2 = new User(3, "Rose");
    private static User user3 = new User(3, "Jack");
    private static List<User> list = Lists.newArrayList(user, user1, user2);
    private static List<User> listDuplicateKey = Lists.newArrayList(user, user1, user2, user3);

    @Test
    void testUniqueKey() {
        Map<Integer, String> map = list.stream()
                .collect(Collectors.toMap(User::getId, User::getName));
        map.forEach((k, v) -> System.out.println(k + "-->" + v));
    }

    /** * toMap默认方法有个参数:throwingMerger(),当key重复值,抛异常: * throw new IllegalStateException(String.format("Duplicate key %s", u)); */
    @Test
    void testDuplicateKeyThrowException() {
        Map<Integer, String> map = listDuplicateKey.stream().collect(Collectors.toMap(User::getId, User::getName));
        map.forEach((k, v) -> System.out.println(k + ": " + v));
    }

    @Test
    void testDuplicateKey() {
        Map<Integer, String> map = listDuplicateKey.stream()
                .collect(Collectors.toMap(User::getId, User::getName, (oldValue, newValue) -> newValue));
        map.forEach((k, v) -> System.out.println(k + "-->" + v));
    }

    /** * Function.identity()获取List里面的泛型属性实体,此方式也是不允许出现重复key */
    @Test
    void testIdentityUniqueKey() {
        Map<Integer, User> map = list.stream().collect(Collectors.toMap(User::getId, Function.identity()));
        map.forEach((k, v) -> System.out.println(k + "-->" + v));
    }

    @Test
    void testIdentityDuplicateKey() {
        Map<Integer, User> map = listDuplicateKey.stream()
                .collect(Collectors.toMap(User::getId, Function.identity(), (oldValue, newValue) -> newValue));
        map.forEach((k, v) -> System.out.println(k + "-->" + v));
    }
}

再来一个小案例:

@Test
public void testToMap() {    
    Person p1 = new Person("kevin", 25);
    Person p2 = new Person("andy", 30);
    Person p3 = new Person("tony", 25);
    Person p4 = new Person("kevin", 20);
    Person p5 = new Person("kevin", 20);
    List<Person> list = new ArrayList<>();
    list.add(p1);
    list.add(p2);
    list.add(p3);
    list.add(p4);
    list.add(p5);
    System.out.println("----->Collectors.toMap,添加处理重复key的参数..");
    Map<String, Person> map = list.stream().collect(Collectors.toMap(person -> person.getName() + "_" + LocalDate.now(), person -> person, (oldValue, newValue) -> newValue));
    System.out.println(JSON.toJSONString(map));
}

打印结果:

----->Collectors.toMap,添加处理重复key的参数..
{"kevin_2019-01-15":{"age":20,"name":"kevin"},"tony_2019-01-15":{"age":25,"name":"tony"},"andy_2019-01-15":{"age":30,"name":"andy"}}

附录:

Collectors.toMap的重载方法:

public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper) {
    return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
}
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction) {
    return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
public static <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) {
    BiConsumer<M, T> accumulator
            = (map, element) -> map.merge(keyMapper.apply(element),
                                          valueMapper.apply(element), mergeFunction);
    return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
    原文作者:你的笑忘书
    原文地址: https://blog.csdn.net/weixin_43563446/article/details/83657736
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞