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);
}