这篇文章主要介绍了 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());
- }
来源: http://www.phperz.com/article/18/0228/358662.html