转换列表<;T>;使用元素列表映射(映射<;F<;T>;,列表<;T>;)Java 7

转换列表<;T>;使用元素列表映射(映射<;F<;T>;,列表<;T>;)Java 7,java,list,dictionary,guava,Java,List,Dictionary,Guava,我找到了一种将列表转换为地图的方法,但我需要 List<Object> to Map<Integer, List<Object> 并列出: List<Movie> movies = new ArrayList<Movie>(); movies.add(new Movie(1, "The Movie 0")); movies.add(new Movie(2, "The Movie 1")); movies.ad

我找到了一种将列表转换为地图的方法,但我需要

List<Object> to Map<Integer, List<Object>
并列出:

    List<Movie> movies = new ArrayList<Movie>();
    movies.add(new Movie(1, "The Movie 0"));
    movies.add(new Movie(2, "The Movie 1"));
    movies.add(new Movie(2, "The Movie 2"));
List movies=new ArrayList();
添加(新电影(1,“电影0”);
添加(新电影(2,“电影1”);
添加(新电影(2,“电影2”);
我想要的是每个级别的列表地图

List<Movie> -> Map<Integer (rank), List<Movie>>
List->Map
用番石榴,我可以做简单的转化

Map<Integer,Movie> mappedMovies = Maps.uniqueIndex(movies, new Function <Movie,Integer> () {
    public Integer apply(Movie from) {
        return from.getRank(); 
}});
Map-mappedMovies=Maps.uniqueIndex(电影,新功能(){
公共整数应用(电影源){
从.getRank()返回;
}});
但不是映射到
Map

我只能在帖子上找到关于它的信息


然而,一种方法使用Java 8,第二种方法出于某种原因返回
ListMultimap

您提到的第二种方法就是您想要的。正如所述,“
ListMultimap
本质上是一个管理列表创建的
Map
。”

因此,您可以使用和来获取
地图

ImmutableListMultimap index=Multimaps.index(电影,新函数(){
@凌驾
公共整数应用(电影源){
从.getRank()返回;
}
});
Map Map=Multimaps.asMap(索引);

虽然您可以使用
Multimap.asMap(ListMultimap)
但是直接使用
Multimap
可能更容易。有关更多详细信息,请参阅的部分。

最简单的方法是使用自己的“添加”实用程序:

static void add(Map<Integer,List<Movie>> map, Movie movie) {
  List<Movie> list = map.get(movie.rank);
  if (list == null) {
    list = new ArrayList<Movie>();
    map.put(movie.rank, list);
  }
  list.add(movie);
}
static void add(地图、电影){
List=map.get(movie.rank);
if(list==null){
列表=新的ArrayList();
map.put(movie.rank,list);
}
列表。添加(电影);
}

ListMultimap
本质上是一个管理列表创建的
Map
。有关如何将其转换为普通贴图的信息,请参阅。谢谢,我采用这种方式,但希望它更干净。是的,谢谢!看起来效果很好,我错过的步骤是“ListMultimap本质上是一个映射”。那么性能呢,用这种方法或者传统的迭代器(如第一个答案中提到的Stefan Haustein,迭代列表并向映射中添加值),哪种方法更有效?@antohoho这取决于您将如何使用它,但我要说的是,使用
多映射
的面向对象好处远远超过了可忽略的性能影响(这可能有利于一种解决方案实现高可变性,而有利于另一种解决方案实现只读使用,等等).我不会在Android上这样做,因为这会影响代码大小,特别是两个匿名类的高静态成本)。我也不认为比相应的传统循环长的代码应该是“更干净”或更可读的,但我想这最终是一个品味问题。注意:
映射。transformValues
步骤是不必要的
ListMultimap.asMap()
保证返回一个
Map
,但它实际上不能使用该返回类型。因此,您可以直接强制转换结果,或者(更好)使用
Multimaps.asMap(ListMultimap)
,它返回
Map
,因此您不必执行任何强制转换。另外请注意:您不必使用
Multimaps.index
。如果您觉得更可取,您可以创建一个
ListMultimap
,然后通过调用
multimap.put(movie.rank,movie)
迭代列表以获得相同的效果。
ImmutableListMultimap<Integer, Movie> index = Multimaps.index(movies, new Function<Movie, Integer>() {
    @Override
    public Integer apply(Movie from) {
        return from.getRank();
    }
});
Map<Integer, List<Movie>> map = Multimaps.asMap(index);
static void add(Map<Integer,List<Movie>> map, Movie movie) {
  List<Movie> list = map.get(movie.rank);
  if (list == null) {
    list = new ArrayList<Movie>();
    map.put(movie.rank, list);
  }
  list.add(movie);
}