Java 8流,将对象列表转换为Map <string,set <string =“” >>

时间:2018-07-17 05:58:30

标签: java java-8 java-stream

我已经讲了几个例子,但这些例子对我没有用。

这就是我想要做的:

我有以下课程的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()));

但这给了我编译错误。 我该如何解决?我的方法有什么问题?

2 个答案:

答案 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;}));

确保您拥有singletontoMap的必要导入,或者分别可以分别使用Collectors.toMap(...)Collections.singleton(...)