从 HashMap 获取值作为参考
Get values from HashMap as reference
是否可以从 HashMap
中获取值列表作为参考
class MyCustomObject {
String name;
Integer id;
MyCustomObject(String name, Integer id){
this.name = name;
this.id = id;
}
}
HashMap<Integer, MyCustomObject> map = new LinkedHashMap<>();
map.put (1, new MyCustomObject("abc",1));
map.put (2, new MyCustomObject("xyz",2));
List<MyCustomObject> list = new ArrayList<>(map.values());
Log.i(TAG,"************ List from HashMap ************");
for (MyCustomObject s : list) {
Log.i(TAG,"name = "+s.name);
}
list.set(0,new MyCustomObject("temp",3));
Log.i(TAG,"************ List from HashMap after update ************");
for (MyCustomObject s : list) {
Log.i(TAG,"name = "+s.name);
}
Log.i(TAG,"************ List from HashMap ************");
List<MyCustomObject> list2 = new ArrayList<>(map.values());
for (MyCustomObject s : list2) {
Log.i(TAG,"name = "+s.name);
}
输出
**************** List from HashMap ***************
name = abc
name = xyz
**************** List from HashMap after update ***************
name = temp
name = xyz
**************** List from HashMap ***************
name = abc
name = xyz
这里如果从 HashMap
获取值列表,它 return 深拷贝。
更新
我的要求
- 我想要来自 HashMap 的值列表,因为我想使用它们的位置访问项目
- 我想保留值的顺序
- 如果我修改提取列表中的任何内容,那么它也应该反映在 HashMap 中
如果有任何第三方库提供这种数据结构,请告诉我,或者处理这种情况的最佳方法是什么
您正在根据 Map
的值创建一个新的 List
:
List<MyCustomObject> list = new ArrayList<>(map.values());
这就是创建值 Collection
副本的原因,List
中的更改无法反映在原始 Map
中。
如果直接修改map.values()
返回的Collection(比如map.values().remove(new MyCustomObject("abc",1))
),会反映到原来Map
的内容中。但是,您将无法在 Collection
上调用 set
,因为 Collection
没有该方法。
Collection values()
Returns a Collection view of the values contained in this map. The
collection is backed by the map, so changes to the map are reflected
in the collection, and vice-versa.
所以使用一个集合并分配 values()
给它。或者 entrySet()
.
尝试使用地图支持的地图条目,您可以通过调用 entrySet()
获得这些条目。这些列表几乎可以像您希望的那样工作(尽管我仍然提倡您直接使用 map.put( key, updatedValue )
.
示例:
Map<String, Integer> map = new HashMap<>();
map.put( "a", 1 );
map.put( "b", 2 );
//you create a list that's not backed by the map here but that isn't a problem
//since the list elements, i.e. the entries, are backed by the map
List<Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
entryList.get(0).setValue( 5 );
System.out.println( map ); //prints: {a=5, b=2} (note that order is a coincidence here)
最后要注意的是:正如我在处理地图顺序时在评论中所说的那样并不总是确定性的(除非你知道你正在处理像 TreeMap
这样的有序地图),因此使用索引可能会引入错误或不良行为。这就是为什么在大多数情况下您至少要检查密钥,因此您要么需要使用 Map.Entry
(顺便说一句,出于充分的理由不能更改其密钥),或者在这种情况下直接使用密钥无论如何,您不需要 list/collection 个值或条目。
是否可以从 HashMap
中获取值列表作为参考
class MyCustomObject {
String name;
Integer id;
MyCustomObject(String name, Integer id){
this.name = name;
this.id = id;
}
}
HashMap<Integer, MyCustomObject> map = new LinkedHashMap<>();
map.put (1, new MyCustomObject("abc",1));
map.put (2, new MyCustomObject("xyz",2));
List<MyCustomObject> list = new ArrayList<>(map.values());
Log.i(TAG,"************ List from HashMap ************");
for (MyCustomObject s : list) {
Log.i(TAG,"name = "+s.name);
}
list.set(0,new MyCustomObject("temp",3));
Log.i(TAG,"************ List from HashMap after update ************");
for (MyCustomObject s : list) {
Log.i(TAG,"name = "+s.name);
}
Log.i(TAG,"************ List from HashMap ************");
List<MyCustomObject> list2 = new ArrayList<>(map.values());
for (MyCustomObject s : list2) {
Log.i(TAG,"name = "+s.name);
}
输出
**************** List from HashMap ***************
name = abc
name = xyz
**************** List from HashMap after update ***************
name = temp
name = xyz
**************** List from HashMap ***************
name = abc
name = xyz
这里如果从 HashMap
获取值列表,它 return 深拷贝。
更新
我的要求
- 我想要来自 HashMap 的值列表,因为我想使用它们的位置访问项目
- 我想保留值的顺序
- 如果我修改提取列表中的任何内容,那么它也应该反映在 HashMap 中
如果有任何第三方库提供这种数据结构,请告诉我,或者处理这种情况的最佳方法是什么
您正在根据 Map
的值创建一个新的 List
:
List<MyCustomObject> list = new ArrayList<>(map.values());
这就是创建值 Collection
副本的原因,List
中的更改无法反映在原始 Map
中。
如果直接修改map.values()
返回的Collection(比如map.values().remove(new MyCustomObject("abc",1))
),会反映到原来Map
的内容中。但是,您将无法在 Collection
上调用 set
,因为 Collection
没有该方法。
Collection values()
Returns a Collection view of the values contained in this map. The collection is backed by the map, so changes to the map are reflected in the collection, and vice-versa.
所以使用一个集合并分配 values()
给它。或者 entrySet()
.
尝试使用地图支持的地图条目,您可以通过调用 entrySet()
获得这些条目。这些列表几乎可以像您希望的那样工作(尽管我仍然提倡您直接使用 map.put( key, updatedValue )
.
示例:
Map<String, Integer> map = new HashMap<>();
map.put( "a", 1 );
map.put( "b", 2 );
//you create a list that's not backed by the map here but that isn't a problem
//since the list elements, i.e. the entries, are backed by the map
List<Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet());
entryList.get(0).setValue( 5 );
System.out.println( map ); //prints: {a=5, b=2} (note that order is a coincidence here)
最后要注意的是:正如我在处理地图顺序时在评论中所说的那样并不总是确定性的(除非你知道你正在处理像 TreeMap
这样的有序地图),因此使用索引可能会引入错误或不良行为。这就是为什么在大多数情况下您至少要检查密钥,因此您要么需要使用 Map.Entry
(顺便说一句,出于充分的理由不能更改其密钥),或者在这种情况下直接使用密钥无论如何,您不需要 list/collection 个值或条目。