我有这个代码。它应该按整数值排序地图。
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实例的参数,我给构造函数一个空的hashmap。此空地图保存在 base 中。然后我用比较器创建树图。然后我将这些东西放在地图中,它会自动更新ValueComparator中名为 base 的引用。为什么地图会自动传递给ValueComparator更新?实际上 base 变量应该仍然是一个空映射。不是吗?
答案 0 :(得分: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");
}
}
答案 1 :(得分:0)
在Java中,对类的引用是按值传递的。因此,当您将空HashMap
传递给ValueComparator
时,您实际上是在bvc
中存储对它的引用。然后,当您修改HashMap
,bvc.base
作为对它的引用时,会“自动更新”。
编辑:考虑到Jon Skeet的回复。
答案 2 :(得分:0)
为什么地图会自动传递给ValueComparator?
将object
变量传递给方法时,会传递reference variable
的副本。因此,调用者和被调用的方法现在都具有相同的引用副本,因此它们将在堆上引用相同的精确object
。这就是为什么另一个变量可以看到一个变量对对象所做的更改
这就是为什么map
会在ValueComparator
中放入内容时自动更新map
。
答案 3 :(得分:0)
实际上,基本变量应该仍然是空地图。不是吗?
不,您拨打ValueComparator bvc = new ValueComparator(map);
由于this.base = base;
以上证明为什么“然后我把这些东西放在地图中并自动更新名为base的ValueComparator中的引用”。