使用Java 8即时创建带有复合键的地图 [英] Create a map with composite key with Java 8 on the fly
问题描述
我想创建一个如下图所示的地图->
I want to create a map like below->
Map<Pair<MyClass.a, MyClass.b>, MyClass>>.
我有一个对象列表->
I have a list of object ->
List<MyClass>
Pair是我的项目中已经存在的一类,所以我想使用它.
Here Pair is a class, already in my project, so I wanted to use it.
我需要帮助才能从Java 8流中创建它.
I need help to create it from a Java 8 stream.
我确实尝试了::
ls.stream().collect(Collectors.toMap(new Pair(MyClass.a, MyClass.b), MyClass));
但是我遇到一个错误.我是Java 8的新手,正在尝试学习它.
But I am getting an error. I am new to Java 8 and trying to learn it.
添加示例:
class Person {
String name ;
int age ;
// Some other variables
}
我有一个List<Person>
列表.
根据我的要求,我需要使用配对类的键= {name,age}.
In my requirement I need a key = {name, age}, using the pair class.
class Pair<T,U> {
Pair(T t, U u) {
this.t = t
this.u = u
}
// Overridden hashCode && equals methods
}
现在我想创建一个像Map<Pair<String, Int>, Person>
我遇到了一个编译器错误,提示不是功能接口".
I was getting a compiler error that said "Not a functional interface".
我确定必须有一种通过java 8流和收集的方法.
I am sure there must be a way via java 8 stream and collect.
推荐答案
要创建函数,必须使用 lambda表达式.编写new Pair(MyClass.a, MyClass.b)
之类的表达式还不够,相反,您需要指定一个带有参数的函数,该函数将是Person
实例,即p -> new Pair<>(p.name, p.age)
.或者,您可以使参数明确:(Person p) -> new Pair<>(p.name, p.age)
.
In order to create a function, you must use a lambda expression. It’s not sufficient an write an expression like new Pair(MyClass.a, MyClass.b)
, instead, you specify a function having a parameter, that will be a Person
instance, i.e. p -> new Pair<>(p.name, p.age)
. Alternatively you may make the parameter explicit: (Person p) -> new Pair<>(p.name, p.age)
.
对于Map
创建操作,您必须确定所需的内容.例如,
For your Map
creation operation, you have to decide, what you want. E.g.,
Map<Pair<String, Integer>, List<Person>> map
= list.stream().collect(Collectors.groupingBy(p -> new Pair<>(p.name, p.age)));
会将每个键映射到具有该名称/年龄组合的所有Person
实例的列表.
will map each key to a list of all Person
instances having that name/age combination.
相反
Map<Pair<String, Integer>, Person> map
= list.stream().collect(Collectors.toMap(p -> new Pair<>(p.name, p.age), p -> p));
会将名称/年龄对映射到单个Person
实例,但如果有多个具有相同密钥的实例,则会引发异常.您可以指定一个函数来解决此类冲突,例如
will map the name/age pairs to a single Person
instance, but throw an exception, if there is more than one with the same key. You can specify a function to resolve such conflicts, e.g.
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
实例结束.
will overwrite the previous occurrence, ending up with the last Person
instance for each name/age combination.
这篇关于使用Java 8即时创建带有复合键的地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!