2012-06-06 35 views
0

我无法理解与列表和映射有关的一些简单代码。以下面的代码为例:了解Java集合中的Java引用

public class test { 

private Map<Integer, List<String>> myMap ; 

public test(){ 
    myMap = new HashMap<Integer, List<String>>(); 
} 

public void addToMap(String ss){ 

    List<String> myTemp = myMap.get(ss); 
    Random r = new Random(); 
    if(myTemp == null){ 

     myTemp = new ArrayList<String>(); 
     myMap.put(r.nextInt(100), myTemp); 
    } 

    myTemp.add(ss); 

} 

public Map<Integer, List<String>> getMap1(){ 
    return myMap; 
} 


public static void main(String args[]){ 

    test myTest = new test(); 
    myTest.addToMap("abdc"); 
    myTest.addToMap("eeer"); 
    System.out.println(myTest.getMap1()); 

} 

} 

究竟是怎样的addToMap()添加新元素到MYLIST地图。更具体地说,当myTemp是一个局部变量并且在其完成执行后被删除,myTemp.add(ss)如何向myMap添加新元素。而且,从addToMap()方法中删除myTemp.add(ss)会在main方法中打印出一个空的HashMap,为什么这样呢? put方法在add方法之前执行时如何将元素插入到映射中?谢谢。

编辑:我编辑了代码,使其更有意义。

+1

此代码是重构和代码审查的候选人... – Xeon

回答

2

不像C++,Java中所有变量引用到真正的对象。所以,当你这样做时

myTemp = new Object(); 

你在堆中创建一个对象,它的引用被复制到堆栈变量myTemp。如果引用被添加到列表(或其他变量)中,则引用的副本被添加到那里。

一旦MYTEMP被破坏,对象仍然活着。异常是当对象的所有引用都不存在时;那么代码无法访问该对象,并且Garbage Collection可以(但不会强制)将其从内存中删除。

1

MYTEMP是参考到列表中。该列表被分配在堆内存中,而myTemp实际上是一个存储在堆栈上的指针。只要您退出该功能,它将被删除,但在堆内存中分配的内存不会被删除。在堆存储器释放时分配的内存当没有引用它们时垃圾收集器

你说得对。当你离开addToMap()方法时,myTemp将被释放(实际上它将从堆栈中移除),但是在堆内存空间中分配的列表将保留。所有使用新的关键字创建的内容都将放置在堆内存空间中。

阅读此链接Java Reference Objects

2

myTemp是没有的事 - 名单 - 这是不是对事物的一个参考。但这并不是你在地图上的具体参考;它是指它所指的东西。地图有自己的参考,因此删除myTemp参考不会影响地图。

1

从一个最佳实践点,调用一个HashMap“MYLIST”在许多方面存在问题。它不是正交的,“mylist”没有告诉你很多关于它的用法。

在回答你的问题,它是一个简单的例子,如果在地图中存在的项目,它被检索和字符串添加到它,如果创建并添加到地图不就行了。只要地图在范围内,对添加到其中的任何列表的引用(即使它们是在函数范围内创建的)都保留在范围内。

然而,这不是一个有用的例子,就好象它混合了命名,并且不提供现实世界的用例。