欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java中实现list或set转map的方法

程序员文章站 2024-03-08 13:49:40
java中实现list或set转map的方法 在开发中我们有时需要将list或set转换为map(比如对象属性中的唯一键作为map的key,对象作为map的value),...

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 (string str : stringlist) { 
  map.put(str, str); 
} 

是否还有更优雅的写法呢?答案是有的。

guava提供了集合(实现了iterables接口或iterator接口)转map的方法,方法定义如下:


/** 

* returns an immutable map for which the {@link map#values} are the given 
 * elements in the given order, and each key is the product of invoking a 
 * supplied function on its corresponding value. 
 * 
 * @param values the values to use when constructing the {@code map} 
 * @param keyfunction the function used to produce the key for each value 
 * @return a map mapping the result of evaluating the function {@code 
 *     keyfunction} on each value in the input collection to that value 
 * @throws illegalargumentexception if {@code keyfunction} produces the same 
 *     key for more than one value in the input collection 
 * @throws nullpointerexception if any elements of {@code values} is null, or 
 *     if {@code keyfunction} produces {@code null} for any value 
 */ 
public static <k, v> immutablemap<k, v> uniqueindex( 
  iterable<v> values, function<? super v, k> keyfunction) { 
 return uniqueindex(values.iterator(), keyfunction); 
} 
 
/** 
 * returns an immutable map for which the {@link map#values} are the given 
 * elements in the given order, and each key is the product of invoking a 
 * supplied function on its corresponding value. 
 * 
 * @param values the values to use when constructing the {@code map} 
 * @param keyfunction the function used to produce the key for each value 
 * @return a map mapping the result of evaluating the function {@code 
 *     keyfunction} on each value in the input collection to that value 
 * @throws illegalargumentexception if {@code keyfunction} produces the same 
 *     key for more than one value in the input collection 
 * @throws nullpointerexception if any elements of {@code values} is null, or 
 *     if {@code keyfunction} produces {@code null} for any value 
 * @since 10.0 
 */ 
public static <k, v> immutablemap<k, v> uniqueindex( 
  iterator<v> values, function<? super v, k> keyfunction) { 
 checknotnull(keyfunction); 
 immutablemap.builder<k, v> builder = immutablemap.builder(); 
 while (values.hasnext()) { 
  v value = values.next(); 
  builder.put(keyfunction.apply(value), value); 
 } 
 return builder.build(); 
} 

这样我们就可以很方便的进行转换了,如下:

list<string> stringlist = lists.newarraylist("t1", "t2", "t3"); 
map<string, string> map = maps.uniqueindex(stringlist, new function<string, string>() { 
  @override 
  public string apply(string input) { 
    return input; 
  } 
}); 

需要注意的是,如接口注释所说,如果function返回的结果产生了重复的key,将会抛出异常。

java8也提供了转换的方法,这里直接照搬别人博客的代码:

@test  
public void convert_list_to_map_with_java8_lambda () {  
    
  list<movie> movies = new arraylist<movie>();  
  movies.add(new movie(1, "the shawshank redemption"));  
  movies.add(new movie(2, "the godfather"));  
  
  map<integer, movie> mappedmovies = movies.stream().collect(  
      collectors.tomap(movie::getrank, (p) -> p));  
  
  logger.info(mappedmovies);  
  
  asserttrue(mappedmovies.size() == 2);  
  assertequals("the shawshank redemption", mappedmovies.get(1).getdescription());  
}  

参考: