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将流派作为键和电影名称作为价值的键。

