三种将list转换为map的方法
1) 传统方法
假设有某个类如下
Java代码
class Movie { private Integer rank; private String description; public Movie(Integer rank, String description) { super(); this.rank = rank; this.description = description; } public Integer getRank() { return rank; } public String getDescription() { return description; } @Override public String toString() { return Objects.toStringHelper(this) .add("rank", rank) .add("description", description) .toString(); } }
1、使用传统的方法:
public void convert_list_to_map_with_java () { 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 = new HashMap<Integer, Movie>(); for (Movie movie : movies) { mappedMovies.put(movie.getRank(), movie); } logger.info(mappedMovies); assertTrue(mappedMovies.size() == 2); assertEquals("The Shawshank Redemption", mappedMovies.get(1).getDescription()); }
2、JAVA 8直接用流的方法
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()); }
(2)转换过程中的两个问题
a、key重复
重复时用后面的value 覆盖前面的value
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(key1 , key2)-> key2 ));
重复时将前面的value 和后面的value拼接起来
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(key1 , key2)-> key1+","+key2 ));
重复时将重复key的数据组成集合
Map<String, List<String>> map = list.stream().collect(Collectors.toMap(Person::getId, p -> { List<String> getNameList = new ArrayList<>(); getNameList.add(p.getName()); return getNameList; }, (List<String> value1, List<String> value2) -> { value1.addAll(value2); return value1; } ));
b、valve为null
在转换流中加上判空,即便value为空,依旧输出
Map<String, List<String>> map = list.stream().collect(Collectors.toMap(Person::getId, p -> { List<String> getNameList = new ArrayList<>(); getNameList.add(p.getName()); return getNameList; }, (List<String> value1, List<String> value2) -> { value1.addAll(value2); return value1; } ))
3、使用guava 工具类库
public void convert_list_to_map_with_guava () { List<Movie> movies = Lists.newArrayList(); movies.add(new Movie(1, "The Shawshank Redemption")); movies.add(new Movie(2, "The Godfather")); Map<Integer,Movie> mappedMovies = Maps.uniqueIndex(movies, new Function <Movie,Integer> () { public Integer apply(Movie from) { return from.getRank(); }}); logger.info(mappedMovies); assertTrue(mappedMovies.size() == 2); assertEquals("The Shawshank Redemption", mappedMovies.get(1).getDescription()); }
--------------------------------------------------------------------------------------------------------------------------------------------------------------------** 分隔符 **--------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、list转map
1 | Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId,Function.identity())); |
二、转换成map的时候,可能出现key一样的情况,如果不指定一个覆盖规则,上面的代码是会报错的。转成map的时候,最好使用下面的方式:
1 | Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key2)); |
三、有时候,希望得到的map的值不是对象,而是对象的某个属性,那么可以用下面的方式:
1 | Map<Long, String> maps = userList.stream().collect(Collectors.toMap(User::getId, User::getAge, (key1, key2) -> key2)); |
四、List 以ID分组 Map<Integer,List>
1 | Map<Integer, List> groupBy = appleList.stream().collect(Collectors.groupingBy(Apple::getId)); |
五、List 以ID分组 Map<Integer,List>,并对list中某一列做特殊处理
1 2 3 4 5 6 7 | Map<Integer, List<Apple>> appleMap = appleList.stream() .peek(t -> { t.setSku(t.getSku().toUpperCase()); //sku转大写 t.setQty(Objects.isNull(t.getQty) ? BigDecimal.ZERO : t.getQty); //数量为null则设为0 t.setPrice(Optional.ofNullable(t.getPrice).orElse(BigDecimal.ZERO)); //价格非null取当前值 如果是null则取0 }) .collect(Collectors.groupingBy(Apple::getId)); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix