2016-06-21 102 views
2

是否有可能从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中

请不要告诉,如果任何第三方库提供这样的数据结构,或者这将是处理这种情况

+2

'List list = new ArrayList <>(map.values());'你认为这行代表什么? – Fildor

+0

这是浅拷贝,你想要什么? – Boola

+0

剧透:https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(java.util.Collection) – Fildor

回答

2

尝试使用地图支持的地图条目,并通过致电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(因为很好的原因,它不能改变密钥),或者直接使用密钥,在这种情况下你不需要无论如何需要一个列表/值的集合或条目。

+0

这是最接近我需要的 – penguin

+0

如果我使用LinkedHashMap而不是HashMap,顺序会是确定性的吗?将map.entrySet()提供的数据总是相同的顺序 – penguin

+0

http://stackoverflow.com/questions/2923856/is-the-order-guaranteed-for-the-return-of-keys-and-values-from-a -linkedhashmap -o/2924143#2924143 – penguin

4

您是基于Map的值创建一个新的List最好的方法:

List<MyCustomObject> list = new ArrayList<>(map.values()); 

这就是创建值Collection的副本,并且该List中的更改不能反映在原始Map中。

如果您直接修改map.values()返回的集合(例如,map.values().remove(new MyCustomObject("abc",1))),它将反映在原始Map的内容中。不过,您不能在Collection上拨打set,因为Collection没有该方法。

2

类别值()

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

因此,使用Collection并将values()赋值给它。或者entrySet()

+0

正是我建议的,即使用'entrySet()'和'entry.setValue(...)'来更新该条目。 – Thomas

+0

@Thomas +1来自我,entrySet比键值经常扮演的角色更多地被用在那里。 –