从 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 深拷贝。

更新

我的要求

  1. 我想要来自 HashMap 的值列表,因为我想使用它们的位置访问项目
  2. 我想保留值的顺序
  3. 如果我修改提取列表中的任何内容,那么它也应该反映在 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 个值或条目。