2016-06-22 3 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; 
    }  
} 

От общественной статической магистрали другого класса.

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 = новые фрукты («Яблоко», 1,3); Фрукты f2 = новые фрукты («Яблоко», 1,1); Фрукты f3 = новые фрукты («Яблоко», 1,2);

Выход прибудет на это

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

Так или иначе мои объекты рассматриваются как же, когда я держу различные элементы по весу и цене. Я не мог понять, почему объекты считаются такими же. Пожалуйста помоги.

+0

Голосование закрывается как ошибка копирования-вставки ('f.price' должен быть' f.weight'). – dasblinkenlight

+0

Реализация вашего компаратора настолько запутанна, что нечитаема, не говоря уже об исправлении. Кроме того, результаты '.compareTo' следует сравнивать с 0, а не 1. –

ответ

1

Основная проблема заключается в том, что вы всегда проверяете, что два поля равны, и только один для разных. В последнем случае это происходит, если по меньшей мере 2 поля отличаются друг от друга, вы возвращаете 0, что означает, что они должны рассматриваться как равные, и именно по этой причине у вас есть эта проблема.

С момента заказа, который вы хотите, нужно сначала отсортировать его по названию, затем по количеству, а затем по цене удалить && f1.price == f2.price с 4-го условия вперед и удалить && 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

У Вас есть ошибка в вашем методе equals в классе Fruits:

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

Я изменил опечатку, но все же поведение не меняется. Я считаю, что мне нужно посмотреть свое сравнение в классе компаратора. Благодарю. – GAK

+0

TreeSet и TreeMap в любом случае не используют методы equals и hashCode. Они будут использоваться для HashSet и HashMap. По этому вопросу они не имеют значения. Посмотрите на мой ответ за правильное исправление. Исправление находится в компараторе. – JackDaniels

1

Сбор, связанный с деревом, не используется equals() или hashCode(). Они вступают в игру за Map.

Ваши условия в compare приводят к 0, поэтому плод не вставлен.

Первое яблоко входит, поскольку дерево пуста. Второй & 3-я Яблока приводит к false во всех if условиях, таким образом возвращая окончательный 0. Поставьте System.out.println() перед окончательным return для подтверждения.

Если вы хотите, чтобы отсортировать фрукты сначала по имени, а затем по весу & тогда, наконец, по цене, вот более компактный способ сделать это:

@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

Ни одно из ваших условий не выполнено. Поместите 'System.out.println (8)' после 7-го, после полного блока 'if', чтобы просмотреть это. В каждом условии 'if' у вас есть хотя бы одно из следующих:' name', 'weight' или' price' равное/'==', тогда как ни один из трех яблок не имеет одинакового 'weight' или' price'. – Vineet

0

TreeSet, при использовании с Comparator, элементы равенство определяется методом compareComparator, в противном случае используется метод compareTo его элемента, поскольку они необходимы для реализации интерфейса Comparable. Методы hashcode и equals будут использоваться только самим интерфейсом Set (например, метод contains использует метод equals, чтобы проверить, представлены ли эти элементы). И hashcode - это не то, что TreeSet используется, когда используется HashSet, что является совершенно другим способом реализации интерфейса Set.Таким образом, в вашем коде, поскольку метод compare, который вы переопределили Comparator, рассматривает эти элементы равными, поэтому их нельзя вставлять несколько раз. В одном руководстве, которое указано в учебном пособии по Java, метод compare должен соответствовать методам equals, то есть элементы должны обрабатываться равными по методу compare тогда и только тогда, когда это делает метод equals.

И в вашем методе equals вы использовали this.weight == f.price, чтобы сравнить два плода, которые я не думаю, что вы намеревались делать. Это делает ваши методы equals несовместимыми с методом compare.

Для справки см. Java Object Ordering учебник, а также a question Я спросил два дня назад.

Смежные вопросы