問題: Java 8 的List 轉成 Map<K, V>
我想要使用Java 8的streams和lambdas轉換一個 List 對象為 Map
下面是我在Java 7里面的寫法
private Map<String, Choice> nameMap(List<Choice> choices) {final Map<String, Choice> hashMap = new HashMap<>();for (final Choice choice : choices) {hashMap.put(choice.getName(), choice);}return hashMap;
}
我可以很輕松地用Java8和Guava搞定,但是呢我又不知道怎么不用Guava搞定
Guava寫法:
private Map<String, Choice> nameMap(List<Choice> choices) {return Maps.uniqueIndex(choices, new Function<Choice, String>() {@Overridepublic String apply(final Choice input) {return input.getName();}});
}
Guava +Java 8 lambdas寫法:
private Map<String, Choice> nameMap(List<Choice> choices) {return Maps.uniqueIndex(choices, Choice::getName);
}
回答一:
基于Collectors 文檔,可以簡寫成為:
Map<String, Choice> result =choices.stream().collect(Collectors.toMap(Choice::getName,Function.identity()));
回答二
如果你的key不保證對于每個list中每個元素都是獨一無二的,你就應該轉換成Map<String, List>而不是Map<String, Choice>
Map<String, List<Choice>> result =choices.stream().collect(Collectors.groupingBy(Choice::getName));
回答三
用 getName() 作為 key 并且Choice 本身作為map的value:
Map<String, Choice> result =choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));
回答四
上述的大部分回答的忽略了一種情況了就是當list有重復元素的時候。這種情況下就會拋出 IllegalStateException,參考下面的代碼去處理重復的list元素吧
public Map<String, Choice> convertListToMap(List<Choice> choices) {return choices.stream().collect(Collectors.toMap(Choice::getName, choice -> choice,(oldValue, newValue) -> newValue));}
回答五
例如你想轉換對象的一些域到map上:
對象是:
class Item{private String code;private String name;public Item(String code, String name) {this.code = code;this.name = name;}//getters and setters}
List 轉 Map的操作是:
List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));Map<String,String> map = list.stream().collect(Collectors.toMap(Item::getCode, Item::getName));
文章翻譯自Stack Overflow:https://stackoverflow.com/questions/20363719/java-8-listv-into-mapk-v