groupingBy to Collection Java8

时间:2015-02-09 10:53:35

标签: java generics collections lambda java-8

我的方法如下:

 public static <T, E>  Map<E, List<T>> groupBy(Collection<T> collection, Function<T, E> function){
    return collection.stream().collect(Collectors.groupingBy(function::apply));
}

它有效,但我希望我的方法看起来像这样:

public static <T, E>  Map<E, Collection<T>> groupBy(Collection<T> collection, Function<T, E> function){
    return collection.stream().collect(Collectors.groupingBy(function::apply));
}

然后它不起作用,因为groupingBy返回Map&lt; E,列表&lt; T&gt;&gt;,而不是Map&lt; E,Collection&lt; T&GT;&GT;

当然我可以这样做:

   public static <T, E>  Map<E, Collection<T>> groupBy(Collection<T> collection, Function<T, E> function){
    return (Map<E, Collection<T>>) (Map) collection.stream().collect(Collectors.groupingBy(function::apply));
}

但我不喜欢这个解决方案。方法声明:

    public static <T, E>  Map<E, Collection<T>> groupBy(Collection<T> collection, Function<T, E> function)

必须保持这种状态(这是任务的一部分)。那么有什么比铸造更好的解决方案?我知道有第二个版本的 groupingBy 作为第二个参数,它需要收集器,它可以改变 groupingBy 返回的地图类型。但是我不知道如何使用它。 有 Collectors.toCollection(),但我认为它仍将返回Collection的一些实现,而不是Collection本身。

也可以按照以下链接编写我的自定义收集器: http://www.nurkiewicz.com/2014/07/introduction-to-writing-custom.html

但我不知道如何将它与Collection一起使用。

我真的很感谢你的帮助,谢谢:)

2 个答案:

答案 0 :(得分:4)

这样的事情应该有效:

public static <T, E>  Map<E, Collection<T>> groupBy(Collection<T> collection, Function<T, E> function){
    return collection.stream()
                     .collect(Collectors.groupingBy(function,
                                                    Collectors.toCollection(ArrayList::new)));
}

这将为ArrayList中的每个值生成Map个实例。如果您愿意,可以选择其他馆藏(只需更改ArrayList::new)。

答案 1 :(得分:1)

您可以提供收集器的类型以及Map的类型:

public static <T, E> Map<E, Collection<T>> groupBy(Collection<T> collection, Function<T, E> function){
    return collection.stream().collect(Collectors.groupingBy(function::apply, HashMap::new,Collectors.toCollection(ArrayList::new)));
}