首先
要使用TreeSet(“有序集”),值(<V>)必须实现Comparable<V>或者我们必须提供@987654325 @@TreeSet 建设。
第二
检查一下(如果我们没看错的话):
package com.example;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
// test data:
List<Person> list = List.of(new Person(1969), new Person(1969), new Person(1969), new Person(1969),
new Person(1969), // 5
new Person(1971), new Person(1971), new Person(1971), new Person(1971),
new Person(1971), // 5
new Person(1999), new Person(1999) // 2
);
// action:
Map<Integer, Set<Person>> stream_exo = list.stream()
.collect( //..as we had
groupingBy( // ...
p -> p.year, // ... key - function
collectingAndThen( // value - "downstream"
toSet(), // collector - function (downstream)
s -> s // (and then) set - (finalizer) fuction
.stream() // stream once more ;(, unfortunately i found no nicer way
.limit(4) // limit to 4, and finally:
.collect( // ...collect
toSet() // to set TreeSet::new, when Person is Comparable<Person>
)
) // end-collectingAndThen
) // end-groupingBy
); // end-collect
// output verification:
stream_exo.forEach((k, v) -> {
System.out.format("%s:\t%d%n", "key", k);
v.forEach(p -> System.out.println(p));
});
}
}
class Person {
final int year;
Person(int pYear) {
year = pYear;
}
}
输出:
key: 1969
com.example.Person@31befd9f
com.example.Person@1c20c684
com.example.Person@2f2c9b19
com.example.Person@13221655
key: 1971
com.example.Person@3e3abc88
com.example.Person@1218025c
com.example.Person@548c4f57
com.example.Person@816f27d
key: 1999
com.example.Person@53d8d10a
com.example.Person@6ce253f1
所以collectingAndThen(再发给stream(),再发给limit(),再发给collect())就是我对这个特殊要求的回答!
第三
如果我们想使用TreeSet,我们必须实现上面提到的(First)接口,“...and finally”:
collect(toSet(TreeSet::new)))));
终于
让它真正成为TreeMap:
TreeMap<Integer, Set<Person>> stream_exo = list.stream()
....
我们需要:
...
groupingBy(
p -> p.year,
TreeMap::new, // do additonally this!
collectingAndThen( ...
还要嵌套TreeSets(不修改Person,基于person.year),就是这样:
TreeMap<Integer, Set<Person>> stream_exo = list // TreeMap result (Integer IS Comparable<Integer>;)
.stream()
.collect(
groupingBy(
p -> p.year,
TreeMap::new,
collectingAndThen(
toSet(), // if we want the "intermediary" set also as TreeSet(ordered!), then here!
s ->
s.stream()
.limit(4)
.collect(
toCollection(() -> { // TreeSet leafs:
return new TreeSet<> ( // with inline comparator
(p1, p2) -> Integer.compare(p1.year, p2.year));
}
)
)
)
);
...但是year 旁边的Comparable<Person> 在这里没用,因为year 已经分组/唯一。;)