Код Java не выводит ожидаемых результатов

Я пишу код о прослушивании с кандидатами из разных городов. Для этого я использую HashMap и TreeSet. Теперь TreeSet не может содержать дубликаты obj, так как в классе Participant есть перегруженный метод equals. Однако Сет все равно добавляет их. Есть ли способ исправить это?

Я пробовал все, что мог придумать, и не могу найти сообщения, связанные с моими вопросами.

код:

package audition;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;


class Audition {
    Map<String,TreeSet<Participant>>participants;
    public Audition() {
        participants=new HashMap<String,TreeSet<Participant>>();
    }
    void addParticpant(String city, String code, String name, int age) {
        Participant p=new Participant(code,name,age);
        if(participants.get(city)==null) {
            participants.put(city, new TreeSet<Participant>() {

                private static final long serialVersionUID = 1L;

                @Override
                public String toString() {
                    StringBuilder sb=new StringBuilder();
                    int br=0;
                    for(Participant p:this) {
                        if(br==this.size()-1)break;
                        br++;
                        sb.append(p).append('\n');
                    }
                    sb.append(this.last());
                    return sb.toString();
                }
            }); 
            participants.get(city).add(p);
        }
        else {

            participants.get(city).add(p);
        }
    }
    void listByCity(String city) {
        System.out.println(participants.get(city));
    }
}

class Participant implements Comparable<Participant>{
    String code;
    String name;
    int age;
    public Participant(String code, String name, int age) {
        this.code = code;
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        Participant p=(Participant)o;
        return this.code.equals(p.code);
    }

    @Override
    public int compareTo(Participant o) {
        // TODO Auto-generated method stub
        if(this.name.compareTo(o.name)==0) {
            return Integer.compare(this.age, o.age);
        }
        return this.name.compareTo(o.name);
    }
    @Override
    public String toString() {
        return code+" "+name+" "+String.valueOf(age);
    }

}
public class AuditionTest {
    public static void main(String[] args) {

        Audition audition = new Audition();
        List<String> cities = new ArrayList<String>();
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            String[] parts = line.split(";");
            if (parts.length > 1) {
                audition.addParticpant(parts[0], parts[1], parts[2],
                        Integer.parseInt(parts[3]));
            } else {
                cities.add(line);
            }
        }
        for (String city : cities) {
            System.out.printf("+++++ %s +++++\n", city);
            audition.listByCity(city);
        }
        scanner.close();
    }
}

> Input: 
> Скопје;001;Ана;17 
> Скопје;002;Борис;19 
> Скопје;002;Иван;15
> Скопје;003;Јована;23 
> Скопје;004;Михаела;18 
> Битола;002;Николина;17
> Битола;001;Стефанија;16 
> Битола;001;Елена;19 
> Битола;005;Анастасија;21
> Битола;004;Игор;20 
> Гевгелија;003;Аце;17 
> Гевгелија;001;Иван;25
> Гевгелија;002;Мартина;15 
> Гевгелија;005;Наташа;19 
> Гевгелија 
> Битола
> Скопје



> my Output:
> +++++ Гевгелија +++++ 
> 003 Аце 17 
> 001 Иван 25 
> 002 Мартина 15 
> 005 Наташа 19
> +++++ Битола +++++ 
> 005 Анастасија 21 
> 001 Елена 19 
> 004 Игор 20 
> 002 Николина 17 
> 001 Стефанија 16
> +++++ Скопје +++++ 
> 003 Јована 23 
> 001 Ана 17  
> 002 Борис 19 
> 002 Иван 15 
> 004 Михаела 18


> expected Output:
> +++++ Гевгелија +++++ 
> 003 Аце 17 
> 001 Иван 25 
> 002 Мартина 15 
> 005 Наташа 19
> +++++ Битола +++++ 
> 005 Анастасија 21 
> 004 Игор 20 
> 002 Николина 17 
> 001 Стефанија 16
> +++++ Скопје +++++ 
> 003 Јована 23 
> 001 Ана 17 
> 002 Борис 19 
> 004 Михаела 18

код написан кириллицей(не важно)


person andrej tetovo    schedule 06.01.2019    source источник
comment
Как и ответ, вы не переопределили hashCode - это не проблема с точки зрения TreeSet, но вы должны переопределять hashCode каждый раз, когда переопределяете equals.   -  person Jon Skeet    schedule 07.01.2019
comment
Пожалуйста, рассмотрите возможность использования более подходящего/конкретного заголовка для вашего вопроса. Если ваша проблема связана с TreeSets и переопределенными методами equals, эти части также должны быть в заголовке.   -  person Yolgie    schedule 07.01.2019


Ответы (2)


Ваш метод compareTo() неверен в соответствии с вашими ожиданиями.
Вы хотите, чтобы ваши ожидаемые коды Participant отличались друг от друга.
Таким образом, compareTo() должен быть:

@Override
public int compareTo(Participant o) {    
    return code.compareTo(o.code);
}

Обратите внимание, что в Comparable javadoc говорится, что:

Настоятельно рекомендуется (хотя и не требуется), чтобы естественные упорядочения соответствовали равным.

С этим изменением так и будет.
Обратите также внимание, что hashCode() также следует последовательно переопределять, если вы переопределяете equals().

person davidxxx    schedule 06.01.2019

TreeSet не использует equals для определения того, равны ли два объекта. Вместо этого он использует compareTo, и если он равен нулю, он считает два объекта равными.

Поэтому вам необходимо убедиться, что то, что вы сравниваете в equals, и то, что вы сравниваете в compareTo, совпадают.

person Joe C    schedule 06.01.2019