使用Java 8的流和收集器将Collection转换为Map转换到方法中

时间:2017-08-24 12:35:10

标签: java collections java-8 java-stream collectors

我相信这个问题并不重复,尽管有很多关于将列表转换为Java 8中的地图的问题。请耐心等待。

我正在尝试做的是逐步为自己构建一个函数库,以避免不得不重复编译一遍又一遍地涉及流和收集器,这往往过于冗长。

目前我一直在创建一个方法,该方法将集合转换为集合对象的某个字段的地图分组。

假设我们有这个课程:

   class SomeClass {
      private String someField;
      private String anotherfield;

      public String getSomeField() {
         return someField;
      }
      public String getAnotherField() {
         return anotherfield;
      }
   }

列表:

  List<SomeClass> myList = new ArrayList<SomeClass>();
  //populate the list...

我们想要这个,其中地图的每个键都是列表对象中someField的唯一值:

Map<String,List<SomeClass>> myMap;

可以这样做:

 Map<String,List<SomeClass>> myMap = 
    myList.stream().collect(Collectors.groupingBy(o -> o.getSomeField()  ));

这是我无法解决的部分。正如我所说,我想把它隐藏在我打算在我的项目中使用的实用程序类中的一个更干净的方法中。该方法的签名:

   public static <T, R> Map<R, List<T>> collectionToMap(
      Collection<T> coll, Function<? super T, ? extends R> groupByKey)

将被称为:

Map<String,List<SomeClass>> amap = collectionToMap(myList, o -> o.getSomeField());

这是一个笨拙的尝试,不能编译,只是为了给你一个想法:

   public static <T, R> Map<R, List<T>> collectionToMap(Collection<T> coll, Function<? super T, ? extends R> groupByKey) {
      Map<R,List<T>> amap = coll.stream().collect(Collectors.groupingBy( 
            T::groupBy,
            Collectors.mapping(T, Collectors.toList())
            ));
      return amap;
   }

我无法绕过它。

1 个答案:

答案 0 :(得分:4)

您不需要mapping。您只需将groupByKey Function传递给groupingBy

public static <T, R> Map<R, List<T>> collectionToMap(Collection<T> coll, Function<? super T, ? extends R> groupByKey) {
    return coll.stream().collect(Collectors.groupingBy(groupByKey));
}