java list 自定义类型转换,如何转换List< V>使用Java 8流以及自定义的List和Map供应商将其导入Map< K,List< V>中?...

It's easy to convert List into Map>. For example:

public Map> getMap(List strings) {

return

strings.stream()

.collect(Collectors.groupingBy(String::length));

}

But I want to do it with my own List and Map suppliers.

I have come up with this:

public Map> getMap(List strings) {

return strings.stream()

.collect(Collectors.toMap(

String::length,

item -> {List list = new ArrayList<>(); list.add(item); return list;},

(list1, list2) -> {list1.addAll(list2); return list1;},

HashMap::new));

}

Question: Is there an easier, less verbose, or more efficient way of doing it? For example, something like this (which doesn't work):

return strings.stream()

.collect(Collectors.toMap(

String::length,

ArrayList::new,

HashMap::new));

And what if I only need to define the List supplier, but not the Map supplier?

解决方案

You could have the following:

public Map> getMap(List strings) {

return strings.stream().collect(

Collectors.groupingBy(String::length, HashMap::new, Collectors.toCollection(ArrayList::new))

);

}

The collector groupingBy(classifier, mapFactory, downstream) can be used to specify which type of map is wanted, by passing it a supplier of the wanted map for the mapFactory. Then, the downstream collector, which is used to collect elements grouped to the same key, is toCollection(collectionFactory), which enables to collect into a collection obtained from the given supplier.

This makes sure that the map returned is a HashMap and that the lists, in each value, are ArrayList. Note that if you want to return specific implementations of map and collection, then you most likely want the method to return those specific types as well, so you can use their properties.

If you only want to specify a collection supplier, and keep groupingBy default map, you can just omit the supplier in the code above and use the two arguments overload:

public Map> getMap(List strings) {

return strings.stream().collect(

Collectors.groupingBy(String::length, Collectors.toCollection(ArrayList::new))

);

}

As a side-note, you could have a generic method for that:

public , M extends Map> M getMap(List list,

Function super V, ? extends K> classifier, Supplier mapSupplier, Supplier collectionSupplier) {

return list.stream().collect(

Collectors.groupingBy(classifier, mapSupplier, Collectors.toCollection(collectionSupplier))

);

}

The advantage with this declaration is that you can now use it to have specific HashMap of ArrayLists as result, or LinkedHashMap of LinkedListss, if the caller wishes it:

HashMap> m = getMap(Arrays.asList("foo", "bar", "toto"),

String::length, HashMap::new, ArrayList::new);

LinkedHashMap> m2 = getMap(Arrays.asList("foo", "bar", "toto"),

String::length, LinkedHashMap::new, LinkedList::new);

but, at that point, it may be simpler to directly use the groupingBy in the code...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值