我想创建一个如下的地图 - >
Map<Pair<MyClass.a, MyClass.b>, MyClass>>.
我有一个对象列表 - &gt;
List<MyClass>
这里的Pair是一个类,已经在我的项目中,所以我想使用它。
我需要帮助才能从Java 8流创建它。
我确实尝试过::
ls.stream().collect(Collectors.toMap(new Pair(MyClass.a, MyClass.b), MyClass));
但是我收到了一个错误。我是Java 8的新手并且正在努力学习它。
添加示例:
class Person {
String name ;
int age ;
// Some other variables
}
我有List<Person>
的列表。
在我的要求中,我需要一个键= {name,age},使用对类。
class Pair<T,U> {
Pair(T t, U u) {
this.t = t
this.u = u
}
// Overridden hashCode && equals methods
}
现在我要创建一个像Map<Pair<String, Int>, Person>
我收到一个编译错误,上面写着“不是功能界面”。
我确信必须通过java 8流和收集方式。
答案 0 :(得分:6)
要创建函数,必须使用 lambda表达式。编写像new Pair(MyClass.a, MyClass.b)
这样的表达式是不够的,而是指定一个具有参数的函数,该函数将是Person
实例,即p -> new Pair<>(p.name, p.age)
。或者,您可以将参数设为显式:(Person p) -> new Pair<>(p.name, p.age)
。
对于Map
创建操作,您必须决定,您想要什么。如,
Map<Pair<String, Integer>, List<Person>> map
= list.stream().collect(Collectors.groupingBy(p -> new Pair<>(p.name, p.age)));
会将每个密钥映射到具有该名称/年龄组合的所有Person
个实例的列表。
相比之下
Map<Pair<String, Integer>, Person> map
= list.stream().collect(Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p));
会将名称/年龄对映射到单个Person
实例,但如果有多个具有相同的键,则抛出异常。您可以指定一个函数来解决此类冲突,例如
Map<Pair<String, Integer>, Person> map = list.stream().collect(
Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p, (first, next) -> first));
将保留第一个,而
Map<Pair<String, Integer>, Person> map = list.stream().collect(
Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p, (prev, last) -> last));
将覆盖上一个匹配项,最后是每个名称/年龄组合的最后一个Person
实例。