java中实现list或set转map的方法
java中实现list或set转map的方法
在开发中我们有时需要将list或set转换为map(比如对象属性中的唯一键作为map的key,对象作为map的value),一般的想法就是new一个map,然后把list或set中的值一个个push到map中。
类似下面的代码:
List<String>stringList=Lists.newArrayList("t1","t2","t3");
Map<String,String>map=Maps.newHashMapWithExpectedSize(stringList.size());
for(Stringstr:stringList){
map.put(str,str);
}
是否还有更优雅的写法呢?答案是有的。
guava提供了集合(实现了Iterables接口或Iterator接口)转map的方法,方法定义如下:
/**
*Returnsanimmutablemapforwhichthe{@linkMap#values}arethegiven
*elementsinthegivenorder,andeachkeyistheproductofinvokinga
*suppliedfunctiononitscorrespondingvalue.
*
*@paramvaluesthevaluestousewhenconstructingthe{@codeMap}
*@paramkeyFunctionthefunctionusedtoproducethekeyforeachvalue
*@returnamapmappingtheresultofevaluatingthefunction{@code
*keyFunction}oneachvalueintheinputcollectiontothatvalue
*@throwsIllegalArgumentExceptionif{@codekeyFunction}producesthesame
*keyformorethanonevalueintheinputcollection
*@throwsNullPointerExceptionifanyelementsof{@codevalues}isnull,or
*if{@codekeyFunction}produces{@codenull}foranyvalue
*/
publicstatic<K,V>ImmutableMap<K,V>uniqueIndex(
Iterable<V>values,Function<?superV,K>keyFunction){
returnuniqueIndex(values.iterator(),keyFunction);
}
/**
*Returnsanimmutablemapforwhichthe{@linkMap#values}arethegiven
*elementsinthegivenorder,andeachkeyistheproductofinvokinga
*suppliedfunctiononitscorrespondingvalue.
*
*@paramvaluesthevaluestousewhenconstructingthe{@codeMap}
*@paramkeyFunctionthefunctionusedtoproducethekeyforeachvalue
*@returnamapmappingtheresultofevaluatingthefunction{@code
*keyFunction}oneachvalueintheinputcollectiontothatvalue
*@throwsIllegalArgumentExceptionif{@codekeyFunction}producesthesame
*keyformorethanonevalueintheinputcollection
*@throwsNullPointerExceptionifanyelementsof{@codevalues}isnull,or
*if{@codekeyFunction}produces{@codenull}foranyvalue
*@since10.0
*/
publicstatic<K,V>ImmutableMap<K,V>uniqueIndex(
Iterator<V>values,Function<?superV,K>keyFunction){
checkNotNull(keyFunction);
ImmutableMap.Builder<K,V>builder=ImmutableMap.builder();
while(values.hasNext()){
Vvalue=values.next();
builder.put(keyFunction.apply(value),value);
}
returnbuilder.build();
}
这样我们就可以很方便的进行转换了,如下:
List<String>stringList=Lists.newArrayList("t1","t2","t3");
Map<String,String>map=Maps.uniqueIndex(stringList,newFunction<String,String>(){
@Override
publicStringapply(Stringinput){
returninput;
}
});
需要注意的是,如接口注释所说,如果Function返回的结果产生了重复的key,将会抛出异常。
java8也提供了转换的方法,这里直接照搬别人博客的代码:
@Test
publicvoidconvert_list_to_map_with_java8_lambda(){
List<Movie>movies=newArrayList<Movie>();
movies.add(newMovie(1,"TheShawshankRedemption"));
movies.add(newMovie(2,"TheGodfather"));
Map<Integer,Movie>mappedMovies=movies.stream().collect(
Collectors.toMap(Movie::getRank,(p)->p));
logger.info(mappedMovies);
assertTrue(mappedMovies.size()==2);
assertEquals("TheShawshankRedemption",mappedMovies.get(1).getDescription());
}
参考:https://www.nhooo.com/article/104114.htm