0

我有这个代码。它应该按整数值对地图进行排序。

public class Main {

    public static void main(String[] args) {

        HashMap<String,Integer> map = new HashMap<>();
        ValueComparator bvc =  new ValueComparator(map);
        TreeMap<String,Integer> sorted_map = new TreeMap<>(bvc);

        map.put("A",5);
        map.put("B",4);
        map.put("C",4);
        map.put("D",2);

        System.out.println("unsorted map: "+map);

        sorted_map.putAll(map);

        System.out.println("results: "+sorted_map);


    }
}

class ValueComparator implements Comparator<String> {

    Map<String, Integer> base;
    public ValueComparator(Map<String, Integer> base) {
        this.base = base;
        System.out.println("Map: " + base);
    }

    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        }
    }
}

它工作正常。但首先作为 ValueComparator 实例的参数,我给构造函数一个空的哈希图。而这张空地图保存在base中。然后我用比较器创建树形图。然后我把这些东西放在地图中,它会自动更新 ValueComparator 中名为base的引用。为什么传递给 ValueComparator 的地图会自动更新?实际上,基本变量应该仍然是一个空映射。不是吗?

4

4 回答 4

2

在java中,所有变量都是按值传递的(引用的副本),所以你将有2个变量引用同一个对象..所以当你改变那个对象时,它会反映在另一个对象中。

例如 :

public class Test{

public static void main(String args []){
   Test test = new Test();
   Collection<String> collection = new LinkedList<>();
   collection.add("a");
   collection.add("b");
   someMethod(collection);
   System.out.println(collection); // will print [a,b];
   modifyCollection(collection);
   System.out.println(collection); // will print [a,b,c];
}

public void modifyCollection(Collection collection){
    collection.add("c");
}

public void someMethod(Collection collection){
    collection = new ArrayList();
    collection.add("nasda");
}

}
于 2013-07-04T18:57:33.070 回答
0

实际上,基本变量应该仍然是一个空映射。不是吗?

不,你打电话的那一刻ValueComparator bvc = new ValueComparator(map);

地图和底图都指的是同一个对象,因为this.base = base;

以上证明了为什么“然后我将这些东西放在地图中,它会自动更新名为 base 的 ValueComparator 中的引用”发生。

于 2013-07-04T19:00:53.907 回答
0

在 Java 中,对类的引用是按值传递的。因此,当您将 empty 传递HashMap给时ValueComparator,实际上是将对它的引用存储在bvc. 然后,当您修改HashMap,bvc.base作为对它的引用时,它会“自动更新”。

编辑:考虑到 Jon Skeet 的回复。

于 2013-07-04T18:58:22.323 回答
0

为什么传递给 ValueComparator 的地图会自动更新?

当你将一个object变量传递给一个方法时,你传递了一个reference variable. 因此,调用者和被调用方法现在都将拥有相同的引用副本,因此两者都将object在堆上引用相同的确切内容。这就是为什么另一个变量可以看到一个变量对对象所做的更改。
这就是为什么当您mapValueComparator内容放入map.

于 2013-07-04T19:00:11.220 回答