返回自己想要的key和value
/**
* toMap
* TODO
* 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);
* }
* @param <T> 输入元素的类型
* @param <K> 键映射函数的输出类型
* @param <U> 值映射函数的输出类型
* @param keyMapper 产生键的映射函数
* @param valueMapper 产生值的映射函数
* @return a {@code Collector} 收集元素的key和value到一个map中,这个map的key和value是应用映射函数的结果对于输入的元素
*
* 如果映射的key 包涵重复会抛出IllegalStateException异常,解决办法使用#toMap(Function, Function, BinaryOperator)}代替
* 返回的Collector不是并发的,对于并行流管道,Combiner函数通过将键从一个映射合并到另一个映射来进行操作,这将是一个很消耗性能的操作。
* 如果不需要将结果按遇到的顺序插入到{@code Map}中,则使用{@link #toConcurrentMap(Function,Function)} 可能会提供更好的并行性能。
*
*/
@Test
public void test_toMap_1(){
List<Student> list = getStudentList();
list.add(new Student(1, "xixi", 12));
// java.lang.IllegalStateException: Duplicate key Student(id=1, name=lisi, age=5) 有异常
// Map<Integer, Student> collect = list.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
//源码给出的解决办法 key 为ID value为name 对于key相同的value 使用逗号拼接,适用于一个联系人同名,电话不同
Map<Integer, String> collect_ = list.stream().collect(Collectors.toMap(Student::getId, Student::getName, (s, a) -> s + ", " + a));
for (Integer key : collect_.keySet()) {
System.out.println("key: " + key + "====value: " + collect_.get(key));
}
System.out.println("'==================='");
Map<Integer, Student> collect_1 = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a, b) -> a.equals(b) && a.hashCode() == b.hashCode() ? a : b));
for (Integer key : collect_1.keySet()) {
System.out.println("key: " + key + "====value: " + collect_1.get(key));
}
System.out.println("'==================='");
// 判断一个对象是否相同equals为true 并且hashcode相同
Map<Integer, Student> collect_2 = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a, b) -> a.getAge() > b.getAge() ? a : b));
for (Integer key : collect_2.keySet()) {
System.out.println("key: " + key + "====value: " + collect_2.get(key));
}
}
使用自定义的合并函数以及返回HashMap
/**
* toMap
* TODO
* 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);
* }
* @param <T> 输入元素的类型
* @param <K> 键映射函数的输出类型
* @param <U> 值映射函数的输出类型
* @param keyMapper 产生键的映射函数
* @param valueMapper 产生值的映射函数
* @param mergeFunction 合并函数,用于解决与同一键关联的值之间的冲突【操作的是值】
*
* 如果映射的key有重复的,那么值的映射函数将被应用于每个相等的元素,同一key对应的value结果的合并使用合并的函数
*/
@Test
public void test_toMap_2(){
List<Student> list = getStudentList();
list.add(new Student(1, "xixi", 12));
/**
* 参数一: 是key
* 参数二: 是value
* 参数三: 合并函数, 这个是用来解决key相同抛出的非法异常,合并函数操作的是值
*
* 以下含义: 生产一个map key 为ID 值为 name 对应相同的key name 使用逗号拼接成value eg:key: 1====value: lisi, xixi
*/
Map<Integer, String> collect_ = list.stream().collect(Collectors.toMap(Student::getId, Student::getName, (s, a) -> s + ", " + a));
for (Integer key : collect_.keySet()) {
System.out.println("key: " + key + "====value: " + collect_.get(key));
}
System.out.println("'==================='");
/**
* key 为ID value 为学生对象,对于key 相同的比较两个对象是否完全相同,是返回之前的,不是返回之后的
*/
Map<Integer, Student> collect_1 = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a, b) -> a.equals(b) && a.hashCode() == b.hashCode() ? a : b));
for (Integer key : collect_1.keySet()) {
System.out.println("key: " + key + "====value: " + collect_1.get(key));
}
System.out.println("'==================='");
}
使用自定义的合并函数以及返回自己想要的集合类型
/**
* toMap
* TODO
* 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);
* }
* @param <T> 输入元素的类型
* @param <K> 键映射函数的输出类型
* @param <U> 值映射函数的输出类型
* @param keyMapper 产生键的映射函数
* @param valueMapper 产生值的映射函数
* @param mergeFunction 合并函数,用于解决与同一键关联的值之间的冲突【操作的是值】
* @param mapSupplier 一个新创建的函数,例如返回的结果将被插入到一个空的Map中
*/
@Test
public void test_toMap_3(){
List<Student> list = getStudentList();
list.add(new Student(1, "xixi", 12));
/**
* key 为ID value 为学生对象,对于key 相同的比较两个对象是否完全相同,是返回之前的,不是返回之后的
*/
Map<Integer, Student> collect_1 = list.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (a, b) -> a.equals(b) && a.hashCode() == b.hashCode() ? a : b, HashMap::new));
for (Integer key : collect_1.keySet()) {
System.out.println("key: " + key + "====value: " + collect_1.get(key));
}
System.out.println("'==================='");
}
案例使用的初始化数据
private List<Student> getStudentList(){
List<Student> sList = new ArrayList<>();
sList.add(new Student(1, "lisi", 5));
sList.add(new Student(2, "wangwu", 7));
sList.add(new Student(3, "maliu", 9));
return sList;
}