2016-06-22 5 views
1

객체를 Treeset에 추가하려고하지만 객체가 모두 추가되지는 않습니다.Java TreeSet이 객체를 추가하지 않습니다.

class Fruits 
{ 
    String name ; 
    int weight; 
    int price; 

    Fruits(String n, int w, int p) 
    { 
     this.name=n; 
     this.weight=w; 
     this.price =p; 
    } 

    @Override 
    public int hashCode() { 
     System.out.println("hashcode called"); 
     int prime =31; 
     int result =1; 
     result = prime*result +(this.name.hashCode()+this.price+this.weight); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     System.out.println("Equals called"); 
     if(null!=obj) 
     { 
      Fruits f= (Fruits) obj; 
      if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

class FruitsComparator implements Comparator<Fruits> 
{ 
    //Order by Name, then quanity and then Price 
    @Override 
    public int compare(Fruits f1, Fruits f2) 
    { 
     if(f1.name.equals(f2.name) && f1.weight == f2.weight && f1.price == f2.price) 
     { 
      System.out.println(1); 
      return 0; 
     } 
     else if(f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price < f2.price) 
     { 
      System.out.println(2); 
      return -1; 
     } 
     else if (f1.name.equals(f2.name) && f1.weight==f2.weight && f1.price > f2.price) 
     { 
      System.out.println(3); 
      return 1; 
     } 
     else if (f1.name.equals(f2.name) && f1.weight<f2.weight && f1.price == f2.price) 
     { 
      System.out.println(4); 
      return -1; 
     } 
     else if (f1.name.equals(f2.name) && f1.weight>f2.weight && f1.price == f2.price) 
     { 
      System.out.println(5); 
      return 1; 
     } 
     else if (f1.name.compareTo(f2.name) <1 && f1.weight==f2.weight && f1.price == f2.price) 
     { 
      System.out.println(6); 
      return -1; 
     } 
     else if (f1.name.compareTo(f2.name) >1 && f1.weight==f2.weight && f1.price == f2.price) 
     { 
      System.out.println(7); 
      return 1; 
     } 
      return 0; 
    }  
} 

다른 클래스의 public static void main.

Fruits f1= new Fruits("Apple",1,3); 
Fruits f2= new Fruits("Apple",10,1); 
Fruits f3= new Fruits("Apple",15,2); 
Set<Fruits> sf = new TreeSet<Fruits>(new FruitsComparator()); 
sf.add(f1); 
sf.add(f2); 
sf.add(f3); 
System.out.println("--Fruits Example--"); 
for(Fruits f: sf) 
{ 
    System.out.println(f.name+"-"+f.weight+"-"+f.price); 
} 

내가 얻을 출력은 다음과 같습니다

--Fruits Example-- 
Apple-1-3 

을하지만 난이 모든 개체 그냥 동일하지만 세 번째 요소 모두를 유지 얻을 아래와 같이 나는 과일 OBJS이있을 때. 과일 f1 = 새로운 과일 ("Apple", 1,3); 과일 f2 = 새로운 과일 ("Apple", 1,1); 과일 f3 = 새로운 과일 ("Apple", 1,2);

이의 출력 GET 내가 무게와 가격에 다른 요소를 유지 그래서 어떻게 든 내 개체가 동일하게 취급됩니다

--Fruits Example-- 
Apple-1-1 
Apple-1-2 
Apple-1-3 

입니다. 나는 왜 물체들이 같은 것으로 취급되는지를 알 수 없었다. 도와주세요.

if(this.name.equals(f.name) && this.price==f.price && this.weight == f.price) 

이 있었어야 :

if(this.name.equals(f.name) && this.price==f.price && this.weight == f.weight) 

이 (마지막 부분에주의)

+0

복사 - 붙여 넣기 오류 ('f.price'는'f.weight' 여야 함)로 닫는 투표. – dasblinkenlight

+0

비교기 구현은 읽을 수 없도록 혼란 스럽습니다. 또한, .compareTo 결과는 1이 아닌 0과 비교되어야합니다. –

답변

1

가장 중요한 문제는 항상 두 개의 입력란이 동일하고 하나만 다른 것으로 확인하는 것입니다. 마지막으로 다른 필드가 2 개 이상 다른 경우 0이 반환됩니다. 이는 0으로 처리해야한다는 것을 의미하므로이 문제가 발생한 이유입니다.

원하는 순서는 이름순으로 정렬하고 수량순으로 정렬 한 다음 가격순으로 정렬하므로 4 번째 조건에서 && f1.price == f2.price을 제거하고 마지막 두 자리에서 && f1.weight==f2.weight을 제거하십시오.


Java 8 스타일을 사용하면이 문제를 완전히 피할 수 있습니다.

Set<Fruits> sf = new TreeSet<Fruits>(Comparator.comparing(Fruits::getName) 
    .thenComparing(Fruits::getWeight) 
    .thenComparing(Fruits::getPrice) 
    ); 

나는 codiva - online java compiler ide에 작업 코드를 추가했습니다. FruitsComparator.java 파일에 약간 더 깔끔한 구현을 포함 시켰습니다.

0

당신은 클래스 Fruitsequals 방법에 오류가 있습니다.

+0

오타가 변경되었지만 여전히 동작이 변경되지 않았습니다. 나는 내가 비교 자 클래스에서 내 비교를 볼 필요가 있다고 생각한다. 감사. – GAK

+0

TreeSet 및 TreeMap은 어쨌든 equals 및 hashCode 메소드를 사용하지 않습니다. 그들은 HashSet과 HashMap에 사용될 것입니다. 이 질문에 대해서는 관련성이 없습니다. 정답을 찾아보십시오. 수정 프로그램이 비교 프로그램에 있습니다. – JackDaniels

1

트리 관련 모음집은 equals() 또는 hashCode()을 사용하지 않습니다. 이 사람들은 Map으로 게임을 시작합니다.

의 조건은 0이되어 과일이 삽입되지 않습니다.

첫 번째 사과는 나무가 비어있어 들어갑니다. 두번째 & 애플은 if 조건에서 false의 결과를 가지므로, 최종 0을 반환합니다. 확인을 위해 return의 앞에 System.out.println()을 넣으십시오. Comparator와 함께 사용할 때 ', 요소

@Override 
public int compare(Fruits f1, Fruits f2) { 
    if (f1.name.equals(f2.name)) { 
     if (f1.weight < f2.weight) { 
      return -1; 
     } else if (f1.weight > f2.weight) { 
      return 1; 
     } else { 
      if (f1.price < f2.price) { 
       return -1; 
      } else if (f1.price > f2.price) { 
       return 1; 
      } else { 
       return 0; 
      } 
     } 
    } else { 
     return f1.name.compareTo(f2.name); 
    } 
} 
+0

감사합니다. 나는 그 문제가있는 곳을 믿는다. 하지만 조건이 내 비교 방법에서 충족되는 이유를 이해할 수 없습니다. 잠시 시간을내어보세요. 감사. – GAK

+0

귀하의 모든 조건이 충족되지 않습니다. 7 번째 이후에'System.out.println (8)'을 배치하고, 완전한'if' 블록 다음에 이것을 봅니다. 'if' 조건에서는'name','weight' 또는'price'가'/= == '와 같지만 하나의 사과가'weight' 나'price'를 가지고 있지 않습니다. – Vineet

0

TreeSet :

그런 다음 최종적 가격 중량 &에 의해, 이름으로 먼저 과일을 정렬 할 경우

, 여기에 그 일을 더 컴팩트 방법 동등성은 Comparatorcompare 메소드에 의해 결정되고, 그렇지 않으면 Comparable 인터페이스를 구현하는 데 필요하므로 해당 요소의 compareTo 메소드를 사용합니다. hashcodeequals 메서드는 메서드를 사용하여 equals 메서드를 사용하여 요소가 표시되는지 확인하는 등의 인터페이스 자체에서만 Set 인터페이스에서 사용됩니다. 그리고 hashcodeTreeSet을 사용하는 반면, HashSetSet 인터페이스를 구현하는 완전히 다른 방법으로 사용합니다.따라서 코드에서 Comparator을 재정의 한 compare 메서드는 이러한 요소를 동일하게 취급하므로 여러 번 삽입 할 수 없습니다. Java Tutorial에서 지적한 지침 중 하나는 compare 메서드가 equals 메서드를 준수해야한다는 것입니다. 즉 equals 메서드가있는 경우에만 compare 메서드에서 요소를 동일하게 처리해야합니다.

귀하의 equals 방법에서는 두 과일을 비교하기 위해 this.weight == f.price을 사용했는데, 의도하지 않은 것입니다. 이로 인해 equals 메서드가 compare 메서드와 일치하지 않게됩니다.

참조 용으로 Java Object Ordering 튜토리얼을 참조하십시오. a question 2 일 전에 질문했습니다.