从HashMap获取值作为参考

时间:2016-06-21 11:07:22

标签: java hashmap linkedhashmap shallow-copy

是否可以从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获取值列表,则返回深层复制。

更新

我的要求

  1. 我想要来自HashMap的值列表,因为我想使用他们的位置访问项目
  2. 我想保留值的顺序
  3. 如果我修改了提取列表中的任何内容,那么它也应该反映在HashMap中
  4. 请告诉我们,如果任何第三方图书馆提供此类数据结构,或者处理这种情况的最佳方法是什么

3 个答案:

答案 0 :(得分:4)

您正在根据List

的值创建新的Map
List<MyCustomObject> list = new ArrayList<>(map.values());

这是创建值Collection副本的原因,而List中的更改无法反映在原始Map中。

如果您直接修改map.values()返回的收藏集(例如map.values().remove(new MyCustomObject("abc",1))),它将反映在原始Map的内容中。但是,您无法在set上致电Collection,因为Collection没有这种方法。

答案 1 :(得分:2)

  

收藏价值()

     

返回此地图中包含的值的Collection视图。该   集合由地图支持,因此反映了对地图的更改   在集合中,反之亦然。

因此,请使用集合并为其指定values()。或entrySet()

答案 2 :(得分:1)

尝试使用地图支持的地图条目,并通过调用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(由于各种原因,btw无法修改密钥)或直接使用密钥,在这种情况下,您不需要列表/值集或条目集合。