我已经讲了几个例子,但这些例子对我没有用。
这就是我想要做的:
我有以下课程的List<SomeClass>
:
class SomeClass {
String rid;
String name;
...
}
我的List
中的值如下:
SomeClass(1,"apple")
SomeClass(1,"banana")
SomeClass(1,"orange")
SomeClass(2,"papaya")
SomeClass(2,"peaches")
SomeClass(3,"melons")
我想将上面的List
转换成Map<String, Set<String>>
,其中rid
字段的键是Set
,值是name
。
要使用Java Streams
解决此问题,我正在使用groupingBy
,我可能会采用以下解决方案:
someClassList
.stream()
.map(SomeClass::getName)
.collect(
Collectors.groupingBy(
SomeClass::getRid, Collectors.toSet()));
但这给了我编译错误。 我该如何解决?我的方法有什么问题?
答案 0 :(得分:6)
当您在.map(SomeClass::getName)
上致电Stream<SomeClass>
时,您会得到Stream<String>
。您无法在collect(Collectors.groupingBy(SomeClass::getRid,...))
上执行Stream<String>
(只能在Stream<SomeClass>
上执行)。
因此,您的map
步骤是错误的。
您需要将Collector
返回的Collectors.mapping()
传递到Collectors.groupingBy()
,以便在之后将SomeClass
实例映射到String
的 它们按getRid
分组。
Map<String, Set<String>> map =
someClassList.stream()
.collect(Collectors.groupingBy(SomeClass::getRid,
Collectors.mapping(SomeClass::getName,
Collectors.toSet())));
答案 1 :(得分:2)
尽管不如groupingBy
收集器可读;您也可以使用toMap
收集器:
myList.stream()
.collect(toMap(SomeClass::getRid, e -> new HashSet<>(singleton(e.getName())),
(l, r) -> {l.addAll(r); return l;}));
确保您拥有singleton
和toMap
的必要导入,或者分别可以分别使用Collectors.toMap(...)
和Collections.singleton(...)
。