使用Java 8动态创建具有组合键的映射

amu*_*u61 1 java-8

我想创建一个类似下面的地图 - >

Map<Pair<MyClass.a, MyClass.b>, MyClass>>.
Run Code Online (Sandbox Code Playgroud)

我有一个对象列表 - >

List<MyClass>
Run Code Online (Sandbox Code Playgroud)

这里的Pair是一个类,已经在我的项目中,所以我想使用它.

我需要帮助从Java 8流创建它.

我试过::

ls.stream().collect(Collectors.toMap(new Pair(MyClass.a, MyClass.b), MyClass));
Run Code Online (Sandbox Code Playgroud)

但是我收到了一个错误.我是Java 8的新手并且正在努力学习它.

添加示例:

class Person {
   String name ;
   int age ;
   // Some other variables
}
Run Code Online (Sandbox Code Playgroud)

我有一份清单List<Person>.

在我的要求中,我需要一个键= {name,age},使用对类.

class Pair<T,U> {     
    Pair(T t, U u) {
        this.t = t
        this.u = u
    }

    // Overridden hashCode && equals methods
}
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个类似的地图 Map<Pair<String, Int>, Person>

我收到一个编译器错误,说"不是一个功能接口".

我相信必须通过java 8流和收集方式.

Hol*_*ger 7

要创建函数,必须使用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)));
Run Code Online (Sandbox Code Playgroud)

将每个键映射到Person具有该名称/年龄组合的所有实例的列表.

相反

Map<Pair<String, Integer>, Person> map
    = list.stream().collect(Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p));
Run Code Online (Sandbox Code Playgroud)

将名称/年龄对映射到单个Person实例,但如果有多个具有相同的键,则抛出异常.您可以指定一个函数来解决此类冲突,例如

Map<Pair<String, Integer>, Person> map = list.stream().collect(
    Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p, (first, next) -> first));
Run Code Online (Sandbox Code Playgroud)

将保持第一,而

Map<Pair<String, Integer>, Person> map = list.stream().collect(
    Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p, (prev, last) -> last));
Run Code Online (Sandbox Code Playgroud)

将覆盖上一个匹配项,最后Person是每个名称/年龄组合的最后一个实例.