Java流列表转换为映射(Map)
时间:2020-02-23 14:35:11 来源:igfitidea点击:
在本教程中,我们将看到如何使用Java 8中的Stream转换为映射。
Collector toMap()
可以与流一起使用以将列表转换为Java中的映射。
考虑一个名字的程序 Movie
有3个字段 id
那 name
和 genre
package org.igi.theitroad; public class Movie { private String name; private String genre; public Movie(String name, String genre) { super(); this.name = name; this.genre = genre; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGenre() { return genre; } public void setGenre(String genre) { this.genre = genre; } @Override public String toString() { return "Movie [name=" + name + ", genre=" + genre + "]"; } }
创建电影列表并使用映射转换为 name
作为关键 genre
作为值。
创建一个名为的类 ConvertListToMapMain
package org.igi.theitroad; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class ConvertListToMapMain { public static void main(String[] args) { List<Movie> moviesList=getListOfMovies(); Map<String, String> moviesMap = moviesList.stream() .collect(Collectors.toMap((m)->m.getName(), (m)->m.getGenre())); System.out.println(moviesMap); } public static List<Movie> getListOfMovies() { List<Movie> moviesList=new ArrayList<>(); Movie m1=new Movie("3 idiots","Comedy"); Movie m2=new Movie("Interstellar","SciFi"); Movie m3=new Movie("Forest gump","Comedy"); Movie m4=new Movie("Matrix","SciFi"); Movie m5=new Movie("The Hangover","Comedy"); moviesList.add(m1); moviesList.add(m2); moviesList.add(m3); moviesList.add(m4); moviesList.add(m5); return moviesList; } }
输出:
{Interstellar=SciFi, Matrix=SciFi, The Hangover=Comedy, Forest gump=Comedy, 3 idiots=Comedy}
moviesMap
包含名称为键和类型为值。
我们还可以使用方法引用而不是LAMDA表达式。
Map<String, String> moviesMap = moviesList.stream() .collect(Collectors.toMap(Movie::getName, Movie::getGenre()));
在重复密钥的情况下会发生什么?
如果存在重复的键,则会抛出重复键 java.lang.IllegalStateException
例外。
假设我们有两个名称的电影 Matrix
public static List<Movie> getListOfMovies() { List<Movie> moviesList=new ArrayList<>(); Movie m1=new Movie("3 idiots","Comedy"); Movie m2=new Movie("Interstellar","SciFi"); Movie m3=new Movie("Forest gump","Comedy"); Movie m4=new Movie("Matrix","SciFi"); Movie m5=new Movie("Matrix","Comedy"); moviesList.add(m1); moviesList.add(m2); moviesList.add(m3); moviesList.add(m4); moviesList.add(m5); return moviesList; }
当我们再次运行ConvertListtomapMain时,我们将得到以下输出:
Exception in thread “main" java.lang.IllegalStateException: Duplicate key Sci Fi at java.util.stream.Collectors.lambda$throwingMergerMap<String, String> moviesMap = moviesList.stream() .collect(Collectors.toMap((m)->m.getName(), (m)->m.getGenre(), (oldValue,newValue) -> newValue ));(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1254) at java.util.stream.Collectors.lambda$toMap(Collectors.java:1320) at java.util.stream.ReduceOpsReducingSink.accept(ReduceOps.java:169) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) at org.arpit.theitroad.ConvertListToMapMain.main(ConvertListToMapMain.java:14)
要解决此问题,我们需要通过合并 BinaryOperator
函数 Collectors.toMap()
。
Map<String, String> moviesMap = moviesList.stream() .collect(Collectors.toMap( (m)->m.getName(), (m)->m.getGenre(), (oldValue,newValue) -> newValue ,TreeMap::new ));
如果我们想要特定映射(Map),如Treemap,该怎么办?
我们可以通过构造方法参考
Collectors.toMap()
获取特定映射(Map)。
package org.igi.theitroad; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class ConvertListToMapMain { public static void main(String[] args) { List<Movie> moviesList=getListOfMovies(); Map<String, List<String>> moviesGenMap = moviesList.stream() .collect(Collectors.groupingBy(Movie::getGenre ,Collectors.mapping(Movie::getName, Collectors.toList()))); System.out.println(moviesGenMap); } public static List<Movie> getListOfMovies() { List<Movie> moviesList=new ArrayList<>(); Movie m1=new Movie("3 idiots","Comedy"); Movie m2=new Movie("Interstellar","SciFi"); Movie m3=new Movie("Forest gump","Comedy"); Movie m4=new Movie("Matrix","SciFi"); Movie m5=new Movie("The Hangover","Comedy"); moviesList.add(m1); moviesList.add(m2); moviesList.add(m3); moviesList.add(m4); moviesList.add(m5); return moviesList; } }
当我们再次运行ConvertListtomapMain时,我们将得到以下输出
正如你所看到的,我们有 TreeMap
按名称排序。
使用收集器获取Multimap.groupBy()
如果,我们希望受欢迎作为键和名称分组的电影为键,那么我们可以使用Colormors.GroupingBy()和收集器。
映射如下:
##代码##moviesGenMap
将流派作为键和电影名称作为价值的键。