2016-12-01 9 views
1
  1. 나는 문자열의 길이에 따라 TreeMap에서 사용자 정의 주문을 시도했습니다. 다른 문자열에도 불구하고 문자열의 길이가 같으면 하나의 Key 만 얻는 이유는 무엇입니까?Java에서 TreeMap에서 오버로드하는 동안 Keyset에서 하나의 키만 가져 오는 이유는 무엇입니까?

  2. 어떻게 수정합니까? equals meth0d에 대한 영향은 무엇입니까? 사용되거나 향후 compareTo가 될 것입니다.

코드 :

import java.util.Comparator; 
import java.util.Map; 
import java.util.TreeMap; 

public class Student implements Comparable { 
    int RollNo; 
    String Name; 
    public Student(int RollNo, String Name) { 
     this.RollNo = RollNo; 
     this.Name = Name; 
    } 

    public int compareTo(Object arg0) { 
     Student str = (Student) arg0; 
     return Integer.valueOf(str.Name.length()).compareTo(Integer.valueOf(this.Name.length())); 
    } 

    public static void main(String[] args) { 
     Map<Student, Integer> mp = new TreeMap<Student, Integer>(); 
     mp.put(new Student(1, "Sameer"), 1); 
     mp.put(new Student(2, "Aameer"), 2); 

     for(Student st : mp.keySet()){ 
      System.out.println((st.Name)); 
     } 
    } 
} 
+0

은 BTW -; this.Name.length '()'는 'compareTo' str.Name.length를 반환()로 wriiten 수있다. – PeterMmm

답변

2

귀하의 compareTo 방법은 그 내용의 String의 이름 대신의 길이를 비교는 같은 길이의 이름을 가진 그래서 Student의는 TreeMap에 의해 동일한 것으로 간주됩니다.

즉, TreeMap에 사용되는 Comparable 또는 Comparator은 키의 순서와 고유성을 결정합니다.

당신은 이름의 길이와 이름 내용 (길이가 동일) 모두에 의해 TreeMap를 주문하여 문제를 해결할 수

: 그 외에

public int compareTo(Object arg0) { 

    Student str = (Student) arg0; 

    int lengthComp = Integer.valueOf(str.Name.length()).compareTo(Integer.valueOf(this.Name.length())); 
    if (lengthComp == 0) { 
     // compare names if the lengths are equal 
     return str.Name.compareTo(this.Name); 
    } else { 
     return lengthComp; 
    } 
} 

, 그것은 수있는 Comparable<Student>를 구현하는 클래스에 대한 더 나은 compareTo 메서드를 사용하여 Student 인수를 허용하십시오.

어떻게 수정해야합니까? equals meth0d에 대한 영향은 무엇입니까? 사용되거나 계속 사용될 것인가?

equalsTreeMap에서 사용하고 compareTo 실제로는 발생하지 않습니다.

-1

답변은 TreeMap.put에 있습니다. 두 문자열은 길이가 같기 때문에 compareTo 메소드를 재정의하면 두 번째 put은 키 값만 바꿉니다.

1

compare()는 두 키 모두에 대해 0을 반환하기 때문에 정렬시 동일하게 간주됩니다. equals()와 일치하는 행동을 비교하는 것이 엄격히 권장되는 이유를 설명하기 위해 https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html을 참조하십시오. 그러나 두 번째 키는 첫 번째 키와 같다고 생각되므로 두 번째 키가 추가되지 않습니다.

해결 방법은 모든 종류의 타이 브레이커를 추가하여 equals와의 일관성을 유지하는 것입니다. 예를 들어, 두 문자열이 같지 않지만 같은 길이의 habe 인 경우 사전 식 순서를 반환하거나 실제 문자를 기반으로 해시를 계산할 수 있습니다.

+0

그래서 여기에 equals를 오버라이드해야합니까 ?? 이 효과는 행동과 동일합니까? – Sameer

+0

equals() ist는이 경우에는 결코 호출되지 않지만 일관성없는 동작을 피하기 위해 a.equals (b) == (a.compare (b) == 0)을 지정하는 것이 좋습니다. 여기에서 equals()를 대체하면 아무 것도 바뀌지 않지만 두 개의 키가 같다고 생각하는 것이 더 분명해질 것입니다. –

0

"Shameer"와 "Aameer"둘 다에 대한 문자열의 길이는 같습니다. 그래서 java compareTo 메소드는 두 값 (길이 고려)이 동일하다고 생각합니다. 따라서 두 객체는 ​​정렬시 동등한 것으로 간주됩니다.

지도 인터페이스에서 키 입력 할 객체를 추가하는 동안이 값이 고유해야 compareTo 메소드를 위반합니다. 위의 값을 추가 할 수 없습니다.

지도 인터페이스에서 중복 키는 이 아닌 것으로 이미 알고 있습니다.

간단한 예를 들어 설명했습니다. 키 값이 같으면 맵 인터페이스에 값을 추가 할 수 없습니다.

import java.util.Map; 
import java.util.TreeMap; 

public class Student2 { 

public static void main(String[] args) { 

    Map<String, Integer> mp = new TreeMap<String, Integer>(); 

    mp.put("Sameer", 1); 
    mp.put("Sameer", 2); 

    for(String st : mp.keySet()){ 
     System.out.println((st)); 
    } 
} 
} 

결과 : 사미르