使用Java 8动态创建具有复合密钥的映射

使用Java 8动态创建具有复合密钥的映射,java,java-8,java-stream,Java,Java 8,Java Stream,我想创建一个如下所示的地图-> Map<Pair<MyClass.a, MyClass.b>, MyClass>>. 但是我犯了一个错误。我刚接触Java8,正在努力学习它 添加一个示例: class Person { String name ; int age ; // Some other variables } 我有一个列表 在我的需求中,我需要一个key={name,age},使用pair类 class Pair<T,U>

我想创建一个如下所示的地图->

Map<Pair<MyClass.a, MyClass.b>, MyClass>>.
但是我犯了一个错误。我刚接触Java8,正在努力学习它

添加一个示例:

class Person {
   String name ;
   int age ;
   // Some other variables
}
我有一个
列表

在我的需求中,我需要一个key={name,age},使用pair类

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

    // Overridden hashCode && equals methods
}
类对{
配对(T,U){
这个。t=t
这个。u=u
}
//重写的hashCode&&equals方法
}
现在我想创建一个类似
map

我收到一个编译器错误,上面写着“不是函数接口”


我确信一定有办法通过Java8流和收集来创建函数。

为了创建函数,必须使用lambda表达式。仅仅编写一个像
newpair(MyClass.a,MyClass.b)
这样的表达式是不够的,相反,您可以指定一个具有参数的函数,该参数将是
Person
实例,即
p->newpair(p.name,p.age)
。或者,您可以显式设置参数:
(Person p)->新对(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, (first, next) -> first));
Map Map=list.stream().collect(
toMap(p->newpair(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));
Map Map=list.stream().collect(
toMap(p->newpair(p.name,p.age),p->p,(prev,last)->last));

将覆盖上一个事件,以每个姓名/年龄组合的最后一个
个人
实例结束。

什么是
MyClass.a
MyClass.b
?它们是
MyClass
的字段吗?只能使用类作为泛型参数,不能使用字段。换句话说,括号
之间可能只有类名,而不是字段名。您希望在结果
映射中包含什么内容?在您的问题中添加一个示例,例如:“对于输入列表…我希望得到以下结果映射:…”您会遇到什么样的错误?这也不清楚。请以更精确的方式重新表述您的问题。@HonzaZidek,我刚刚添加了一个简单的示例。您的类如何定义
equals()
hashCode()
?它是否仅依赖于(确切地说)要用于密钥的两个字段?你还没有解决其他问题。恐怕您试图理解Java8的特性还为时过早:)从理解Java泛型开始。
Map<Pair<String, Integer>, Person> map
    = list.stream().collect(Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p));
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));