我有一个课程说Level(它只是一个理解的虚拟课)。
我想要一个基于levelId的排序TreeMap<Level,Set<String>>
。
请在下面找到代码
import java.util.*;
import java.util.stream.Collectors;
public class Level {
int levelId;
public Level(int levelId) {
this.levelId = levelId;
}
public static Level getLevel(String name){
return new Level(name.length());
}
public static void main(String[]args){
Set<String> names=new HashSet<>();
names.add("Mahesh");
names.add("Ram");
names.add("Rita");
Map<Level, Set<String>> map = names.stream().collect(
Collectors.groupingBy(name->Level.getLevel(name),
Collectors.mapping(name->name,Collectors.toSet())));
}
}
我也试过了Collectors.collectingAndThen()
。
感谢任何帮助。
提前致谢。
答案 0 :(得分:4)
您修改后的工作代码如下所示,请参阅@ 4castle评论:
{{1}}
答案 1 :(得分:4)
如果您不想让Level
实施Comparable
,则需要Comparator
。然后,您必须使用此分隔符作为地图工厂向TreeMap
收集器传递创建groupingBy
的lambda表达式:
public class Level {
int levelId;
public Level(int levelId) {
this.levelId = levelId;
}
public static Level getLevel(String name){
return new Level(name.length());
}
public int getLevelId() {
return levelId;
}
public static void main(String[]args){
Set<String> names=new HashSet<>();
names.add("Mahesh");
names.add("Ram");
names.add("Rita");
Comparator<Level> c = Comparator.comparingInt(Level::getLevelId);
Map<Level, Set<String>> map = names.stream()
.collect(Collectors.groupingBy(
Level::getLevel, () -> new TreeMap<>(c), Collectors.toSet()));
}
}
答案 2 :(得分:1)
在我看来,使用流只能在最简单的情况下提高可读性。如果您有特定要求,例如需要特定Map
实施,或者需要使用自定义Comparator
,我强烈建议您使用for循环。是的,您可以在Collectors
类中搜索适当的方法,但我相信如果您需要稍后再进行一次小更改,则生成的代码更难以遵循并且不太灵活。
在Java 8中,对Map
接口进行了许多改进,这意味着在循环中执行此类操作现在比以前更少痛苦。
Map<Level, Set<String>> result = new TreeMap<>(Comparator.comparingInt(level -> level.levelId));
for (String name : names)
result.computeIfAbsent(getLevel(name), k -> new HashSet<>()).add(name);
在这种情况下,我不确定为什么你想要一张带有Level
键的地图。既然您想按ID进行分组,那么密钥是Integer
是不是更有意义?
Map<Integer, Set<String>> result = new TreeMap<>();
for (String name : names)
result.computeIfAbsent(getLevel(name).levelId, k -> new HashSet<>()).add(name);