3 回答

TA貢獻(xiàn)1757條經(jīng)驗(yàn) 獲得超7個(gè)贊
您在這里有一些選擇。最簡(jiǎn)單的方法是鏈接您的收藏家:
Map<String, Map<Integer, List<Person>>> map = people
.collect(Collectors.groupingBy(Person::getName,
Collectors.groupingBy(Person::getAge));
然后,要使用18歲的年輕人Fred的清單,您可以使用:
map.get("Fred").get(18);
第二種選擇是定義一個(gè)代表分組的類(lèi)。這可以在Person內(nèi)部:
class Person {
public static class NameAge {
public NameAge(String name, int age) {
...
}
// must implement equals and hash function
}
public NameAge getNameAge() {
return new NameAge(name, age);
}
}
然后,您可以使用:
Map<NameAge, List<Person>> map = people.collect(Collectors.groupingBy(Person::getNameAge));
并搜索
map.get(new NameAge("Fred", 18));
最后,如果您不想實(shí)現(xiàn)自己的組類(lèi),那么周?chē)脑S多Java框架都有一個(gè)pair專(zhuān)門(mén)用于此類(lèi)事情的類(lèi)。例如:apache commons pair如果您使用這些庫(kù)之一,則可以將地圖的名稱(chēng)和年齡配對(duì):
Map<Pair<String, Integer>, List<Person>> map =
people.collect(Collectors.groupingBy(p -> Pair.of(p.getName(), p.getAge())));
并使用:
map.get(Pair.of("Fred", 18));
我個(gè)人真的不喜歡這些元組庫(kù)。它們似乎與良好的OO設(shè)計(jì)完全相反:它們隱藏意圖而不是公開(kāi)意圖。
話雖如此,您可以通過(guò)定義自己的分組類(lèi)來(lái)組合后兩個(gè)選項(xiàng),而僅通過(guò)擴(kuò)展即可實(shí)現(xiàn)Pair-從而節(jié)省了很多定義equals等工作,并且將元組的使用隱藏為任何其他便捷的實(shí)現(xiàn)細(xì)節(jié)其他集合。
祝好運(yùn)。

TA貢獻(xiàn)1843條經(jīng)驗(yàn) 獲得超7個(gè)贊
這里看一下代碼:
您可以簡(jiǎn)單地創(chuàng)建一個(gè)功能,讓它為您完成工作,一種功能樣式!
Function<Person, List<Object>> compositeKey = personRecord ->
Arrays.<Object>asList(personRecord.getName(), personRecord.getAge());
現(xiàn)在,您可以將其用作地圖:
Map<Object, List<Person>> map =
people.collect(Collectors.groupingBy(compositeKey, Collectors.toList()));
干杯!

TA貢獻(xiàn)1864條經(jīng)驗(yàn) 獲得超2個(gè)贊
該groupingBy方法具有的第一個(gè)參數(shù)是Function<T,K>:
@param <T>輸入元素的類(lèi)型
@param <K>鍵的類(lèi)型
如果在您的代碼中將lambda替換為匿名類(lèi),則可以看到以下內(nèi)容:
people.stream().collect(Collectors.groupingBy(new Function<Person, int>() {
@Override
public int apply(Person person) {
return person.getAge();
}
}));
剛才更改輸出參數(shù)<K>。例如,在這種情況下,我使用了org.apache.commons.lang3.tuple中的pair類(lèi)按名稱(chēng)和年齡進(jìn)行分組,但是您可以根據(jù)需要?jiǎng)?chuàng)建自己的類(lèi)以過(guò)濾組。
people.stream().collect(Collectors.groupingBy(new Function<Person, Pair<Integer, String>>() {
@Override
public YourFilter apply(Person person) {
return Pair.of(person.getAge(), person.getName());
}
}));
最后,用lambda back替換后,代碼如下所示:
Map<Pair<Integer,String>, List<Person>> peopleByAgeAndName = people.collect(Collectors.groupingBy(p -> Pair.of(person.getAge(), person.getName()), Collectors.mapping((Person p) -> p, toList())));
添加回答
舉報(bào)