我们常常会遇到集合之间的转换,例如:List集合转换成Map的集合,Map的集合转换为List的集合。通常情况下我们都需要进行集合的遍历,然后进行转换,这个实现略low,包括甲骨文公司自己也认识到了这个问题,所以在Java8中引入了流机制来实现非遍历的转换。Java8一下版本的JDK我们可以使用Guava来实现非遍历的集合转换。

下面给我几个常见的非遍历的集合转换示例。

List转MultiMap

这个是最常见的一种数据结构的转换,常见的场景如下:
1 计算每个班级所有学生的平均分(将学生按照班级聚合成MultiMap)
2 计算每个城市酒店的平均产单量(将酒店按照城市聚合成MultiMap)
如果是传统的Java实现方式,则必须进行遍历:

1
2
3
4
5
6
7
8
9
List<Hotel> hotelList = new ArrayList<>();
...
Map<String,List<Hotel>> cityHotelMap = new HashMap<String,List<Hote>>
for(Hotel hotel:hotelList){
if(!cityHotelMap.contrains(hotel.getCityCode())){
cityHotelMap.put(hotel.getCityCode(),new ArrayList<Hotel>())
}
cityHotelMap.get(hotel.getCityCode()).add(hotel);
}

采用Guava的无遍历实现:

1
2
3
4
5
6
7
8
List<Hotel> hotelList = new ArrayList<>();
....
MultiMap<String,Hotel> cityHotelMap = MultiMaps.index(hotelList,new Function(){
@Override
public String apply(Hotel input) {
return input.getCityCode();
}
})

List转Map

List转换成Map如果采用Java的实现,也需要进行遍历。下面直接贴出Guava实现的代码。
如下的例子:将一个酒店列表,转换成按照hotelSeq聚合的Map。

1
2
3
4
5
6
7
8
List<Hotel> hotelList = new ArrayList<>();
....
Map<String,Hotel> hotelMap = Maps.uniqueIndex(hotelList,new Function(){
@Override
public String apply(Hotel input) {
return input.getHotelSeq();
}
})

MultiMap的遍历

1
2
3
4
5
6
7
for(Map.Entry<String,Collection<Hotel>> entry:cityHotelMap.asMap().entrySet()){
String cityCode = entry.getKey();
Collection<Hotel> hotelCollections = entry.getValue();
......
}

MultiMap转List

MultiMap转换成List有几种情况:

  • 将所有的Key转换成List
  • 将所有的Value集合转换成Map

将MultiMap的key转换成List

1
Set<String> cityCodeList = cityHotelMap.keySet()

将MultiMap的value集合转换成

1
List<Hotel> hotelList = cityHotelMap.values()