【发布时间】:2018-07-28 09:26:06
【问题描述】:
将Map<key,value> 转换为List<value> 的最佳方法是什么?只需遍历所有值并将它们插入列表中还是我忽略了什么?
【问题讨论】:
-
我认为如果必须将地图转换为列表,这不是一个好模型。应该以不会出现这种情况的方式编写代码。
标签: java list collections map
将Map<key,value> 转换为List<value> 的最佳方法是什么?只需遍历所有值并将它们插入列表中还是我忽略了什么?
【问题讨论】:
标签: java list collections map
List<Value> list = new ArrayList<Value>(map.values());
假设:
Map<Key,Value> map;
【讨论】:
Collection 到List 的演员阵容会起作用。
keySet() 和 values() 返回的集合通常是 shim 对象,它们提供底层结构的 Set 或 Collection 视图(keySet() 返回一个 Set 以强调没有欺骗)。对于values(),返回的对象可能是List,但通常不会。正如您所说,创建一个真正的列表会破坏链接,这意味着您不再依赖于原始地图。但有时,您只需要一个 List,因为某些 API 需要一个 - 强化了一个规则,即一个好的 API 应该只需要它可以摆脱的最抽象的接口......
一份清单?
假设map 是您的Map 实例
map.values() 将返回一个包含所有地图值的 Collection。map.keySet() 将返回一个包含地图所有键的 Set。【讨论】:
这里的问题是Map 有两个值(键和值),而List 只有一个值(一个元素)。
因此,最好的办法是获取键或值的List。 (除非我们制作一个包装器来保存键/值对)。
假设我们有一个Map:
Map<String, String> m = new HashMap<String, String>();
m.put("Hello", "World");
m.put("Apple", "3.14");
m.put("Another", "Element");
可以通过从Set 方法返回的Set 创建一个新的ArrayList 来获得List 形式的密钥:
List<String> list = new ArrayList<String>(m.keySet());
虽然可以通过Map.values 方法返回的Collection 创建一个新的ArrayList,但可以获得List 形式的值:
List<String> list = new ArrayList<String>(m.values());
得到List的keys的结果:
得到List的值的结果:
【讨论】:
HashMap 和类似的未排序Map 实现,它实际上是随机的.
我猜您想将Map 中包含的值转换为list?最简单的是调用Map接口的values()方法。这将返回 Map 中包含的值对象的 Collection。
请注意,此Collection 由Map 对象支持,对Map 对象的任何更改都将反映在此处。因此,如果您想要一个不绑定到 Map 对象的单独副本,只需创建一个新的 List 对象,如 ArrayList 传递值 Collection,如下所示。
ArrayList<String> list = new ArrayList<String>(map.values());
【讨论】:
map.entrySet() 为您提供包含键和值的 Map.Entry 对象的集合。然后您可以将其转换为您喜欢的任何集合对象,例如new ArrayList(map.entrySet());
【讨论】:
如果要确保结果 List<Value> 中的值在输入 Map<Key, Value> 的键顺序中,则需要以某种方式“通过”SortedMap。
开始使用具体的SortedMap 实现(例如TreeMap)或将您的输入Map 插入SortedMap,然后再将其转换为List。例如:
Map<Key,Value> map;
List<Value> list = new ArrayList<Value>( new TreeMap<Key Value>( map ));
否则,您将获得 Map 实现提供的任何本机排序,这通常可能不是自然键排序(尝试Hashtable 或ConcurrentHashMap,以获得多样性)。
【讨论】:
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("java", 20);
map.put("C++", 45);
Set <Entry<String, Integer>> set = map.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
我们可以在列表中同时拥有键和值对。也可以使用 Map.Entry 通过迭代列表来获取键和值。
【讨论】:
你可以这样做
List<Value> list = new ArrayList<Value>(map.values());
【讨论】:
使用 Java 8 Streams API。
List<Value> values = map.values().stream().collect(Collectors.toList());
【讨论】:
Map<String, String > map = new HapshMap<String, String>;
map.add("one","java");
map.add("two", "spring");
Set<Entry<String, String>> set = map.entrySet();
List<Entry<String, String>> list = new ArrayList<Entry<String, String>> (set);
for(Entry<String, String> entry : list) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
【讨论】:
HashMap<Integer, List<String>> map = new HashMap<>();
List<String> list = new ArrayList<String>();
list.add("Java");
list.add("Primefaces");
list.add("JSF");
map.put(1,list);
if(map != null){
return new ArrayList<String>((Collection<? extends String>) map.values());
}
【讨论】:
这是从地图获取值的通用方法。
public static <T> List<T> ValueListFromMap(HashMap<String, T> map) {
List<T> thingList = new ArrayList<>();
for (Map.Entry<String, T> entry : map.entrySet()) {
thingList.add(entry.getValue());
}
return thingList;
}
【讨论】:
// you can use this
List<Value> list = new ArrayList<Value>(map.values());
// or you may use
List<Value> list = new ArrayList<Value>();
for (Map.Entry<String, String> entry : map.entrySet())
{
list.add(entry.getValue());
}
【讨论】:
如果你想要一个 不可变 值的副本:
List<Value> list = List.copyOf(map.values())
【讨论】:
List.copyOf的包?
java.util.List?