2013-07-04 2 views
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 인스턴스의 매개 변수로 빈 생성자에 빈 해시 맵을 지정합니다. 그리고이 빈지도는 베이스에 저장됩니다. 그런 다음 비교기로 트리 맵을 만듭니다. 그런 다음 물건을지도에 넣고 ValueComparator의 참조를 이라는 참조를 자동으로 업데이트합니다. ValueComparator에 전달 된지도가 자동으로 업데이트되는 이유는 무엇입니까? 사실 베이스 변수는 여전히 빈지도 여야합니다. 그렇지 않니?

답변

0

사실 기본 변수는 여전히 빈지도 여야합니다. 그렇지 않니? "그럼 난지도에 물건을 넣어 자동으로 업데이트하는 이유

없음,지도 및베이스 맵 모두 위 때문에 this.base = base;

의, 같은 객체를 참조되고 ValueComparator bvc = new ValueComparator(map);

전화 할 순간 정당화 ValueComparator에서 base라는 참조가 발생합니다.

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"); 
} 

} 
0

, 클래스 참조를 통과하여 값이다. 따라서 비어있는 HashMapValueComparator에 전달하면 실제로는 bvc에 참조가 저장됩니다. 그런 다음 HashMap을 수정하면 참조 인 bvc.base이 "자동으로 업데이트됩니다."

편집 : Jon Skeet의 답장을 고려하십시오.

+0

아니요, Java는 값으로 전달되지만 * 참조는 값으로 전달됩니다. 참조로 전달하는 것은 참된 통과를 참조로 이해하는 사람들에게 혼동을줍니다. –

+0

항상 그렇습니까? 그래서 문자열을 생성자에 전달한 다음 문자열을 변경 한 다음 문자열을 출력하는 생성 된 클래스에서 일부 메서드를 호출 할 수 있습니다. 새로운 문자열일까요? – MinecraftShamrock

+0

@MinecraftShamrock String은 변경할 수 없습니다. 그러나 메서드에서 문자열을 재 할당하고 호출자에서 sys.out을 반환하면 메서드를 호출하기 전과 동일한 값을 갖게됩니다. 그렇다면 자바가 값으로 전달된다는 사실을 알 수 있습니다. –

0

지도가 ValueComparator로 자동으로 업데이트되는 이유는 무엇입니까? 당신이 방법 내로 object 변수를 전달하는 경우

, 당신은 reference variable의 사본을 전달합니다. 따라서 호출자와 호출 된 메소드 모두 이제 동일한 참조 사본을 가지므로 둘 다 힙에 정확히 동일한 object을 참조합니다. 그래서 한 변수에 의해 변경된 객체가 다른 변수에 의해 나타나는 이유입니다.
map에 물건을 넣을 때 map이 (가) ValueComparator에 자동으로 전달 된 이유는 그 때문입니다.