Java8使用stream的List转map遇到的问题。
首先简单介绍一下Java8的新特性,Lambda表达式。一句话总结一下,就是一个匿名类函数或者叫闭包。他带来的好处是可以动态的去操作我们需要操作的数据结构。
平时开发的时候使用比较多的就是List转Map,比如:
public static void main(String[] arg){
List<Test> testList = new ArrayList<>();
Map<Integer, Test> testMap = testList.stream().collect(Collectors.toMap(Test::getId, test -> test));
}
@Data
private static class Test {
private Integer id;
private String name;
}
我创建了一个Test的对象,将Test对象的集合转换成map。但从逻辑上来说,这是一点问题都没有的。
但是测试过后就会发现不对劲,让我们添加几组数据进行测试。
public static void main(String[] arg){
List<Test> testList = new ArrayList<>();
testList.add(new Test(1, "test"));
testList.add(new Test(2, "test"));
testList.add(new Test(3, "test"));
testList.add(new Test(1, "test"));
Map<Integer, Test> testMap = testList.stream().collect(Collectors.toMap(Test::getId, test -> test));
}
@Data
@AllArgsConstructor
private static class Test {
private Integer id;
private String name;
}
编译发现,会出现一个很典型的错误。
Exception in thread "main" java.lang.IllegalStateException: Duplicate key FtpUtil.Test(id=1, name=test)
异常说的很清楚,就是转换map的时候出现键值重复,所以需要解决这样一个异常。
直接上代码:
Map<Integer, Test> testMap = testList.stream().collect(Collectors.toMap(Test::getId, Function.identity(),
(test1, test2) -> test1));
/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
static <T> Function<T, T> identity() {
return t -> t;
}
我们用到了Function这个接口, 官方说明的很清楚,返回一个需要使用的数据。