2016-02-23 62 views
2

我找到了一種方法來改造List<Object> to a Map<Integer, Object>但我需要轉換列表<T>與元素清單地圖(地圖<F<T>,列表<T>>)的Java 7

List<Object> to Map<Integer, List<Object> 

比如我有類

class Movie { 
    public int rank; 
    public String desc; 

    public Movie(int rank, String desc) { 
     this.rank = rank; 
     this.desc = desc; 
    } 
} 

和列表:

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<Movie> -> Map<Integer (rank), List<Movie>> 

與番石榴我可以做簡單的變換一樣,

Map<Integer,Movie> mappedMovies = Maps.uniqueIndex(movies, new Function <Movie,Integer>() { 
    public Integer apply(Movie from) { 
     return from.getRank(); 
}}); 

但並不是Map<Integer, List<Movie>>

我只能找到關於它的帖子

Java: how to transform from List<T> to Map<f1(T), List(f2(T))> without iterating

然而,一種方法是使用Java 8,第二種方法由於某種原因返回ListMultimap<Integer, String>

+1

'ListMultimap '本質上是一個'地圖>'管理列表的創建爲您服務。請參閱http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ListMultimap.html#asMap(),瞭解如何將其轉換爲普通地圖 – Kiskae

回答

5

您提到的第二種方法是你想要的。由於Kiskaecommented,「ListMultimap<K,V>本質上是一個Map<K,List<V>>,它爲您管理列表的創建。」

因此,您可以使用Multimaps.index(Iterable, Function)Multimaps.asMap(ListMultimap)獲得Map<F<T>, List<T>>

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); 

雖然可以使用Multimaps.asMap(ListMultimap)可能更容易直接使用Multimap。有關更多詳細信息,請參閱的Multimap部分。

+0

是的,謝謝!似乎很好地工作,我錯過了一步「ListMultimap 本質上是一個地圖>」。怎麼樣的性能,什麼會更有效率,這種方式或者只是傳統的迭代器(就像Stefan Haustein在第一個答案中提到的那樣,遍歷列表並向地圖添加值http://stackoverflow.com/questions/35568044/transform-listt -to-map-with-list-of-elements-mapft-listt-java-7/35579317#35579317)? – antohoho

+0

@antohoho這取決於你將如何使用它,但我會說使用'Multimap'的面向對象的好處遠遠超過了可忽略的性能影響(這可能有利於一個解決方案的高可變性,並有利於讀取不同的解決方案 - 僅限使用等)。 – mfulton26

+0

由於代碼大小的影響,我不會在Android上這樣做,特別是兩個匿名類的高靜態成本)。我也沒有看到比相應的傳統循環更長的代碼應該是「更乾淨」還是更具可讀性,但我想這最終是一個有趣的問題。 –

0

最簡單的方法seeems有自己的 「添加」 工具:

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); 
} 
+0

謝謝,我以這種方式,但希望它更清潔的方式 – antohoho

相關問題