Java 代码未输出预期结果

Java code doesn't output expected results

我正在编写有关与来自不同城镇的候选人进行试镜的代码。为此,我使用 HashMap 和 TreeSet。现在 TreeSet 不能包含重复的对象,因为在 Participant class 中重载了 equals 方法。 但是 Set 无论如何都会添加它们。 有什么办法可以解决这个问题吗?

我已经尝试了所有我能想到的方法,但找不到与我的问题相关的帖子。

代码:

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

代码是用西里尔字母写的(不重要)

A TreeSet 不使用 equals 来确定两个对象是否相等。它改为使用 compareTo,如果等于零,则认为两个对象相等。

因此,您需要确保在 equals 中比较的内容与在 compareTo 中比较的内容匹配。

根据您的预期,您的compareTo()方法不正确。
您希望在预期中有不同的 Participant 代码。
所以 compareTo() 应该是:

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

请注意 Comparable javadoc 说:

It is strongly recommended (though not required) that natural orderings be consistent with equals.

有了这个改变,情况就会如此。
另请注意,如果您覆盖 equals().

hashCode() 也应始终被覆盖