0

我正在实现一个按人的年龄排序的 TreeSet,但如果人的名字相等,则不会将一个人保存在集合中。我实现了equals和hashcode,但是这个集合会保存所有人,即使他们有相同的名字。我不知道为什么。

public class Person implements Comparable<Person>{
    private String name;
    private int age;

    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person o) {
        if(this.getAge()<o.getAge()){
            return -1;
        }
        return this.getAge() == o.getAge()?0:1;
    }

    @Override
    public boolean equals(Object object){
        return name.equals(((Person)object).getName());
    }

    @Override
    public int hashCode(){
        return name.hashCode();
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

    public static void main(String[] args){
        Set<Person> set = new TreeSet<Person>();
        set.add(new Person("Jack",30));
        set.add(new Person("Jack",20));
        System.out.println(set);
    }
}
4

4 回答 4

3

你可以加

if(name.equals(o.getName())) {
    return 0;
}

在你的compareTo()功能开始。这种方式 TreeSet 可以假设a.equals(b)等效于a.compareTo(b) == 0并且您仍然可以按年龄排序,因为集合中的所有名称都不同。

于 2012-04-12T06:37:21.253 回答
2

你不能那样做。equals 和 compareTo 必须做“同样的事情”。也就是说,如果 equals 返回 true,compareTo 应该返回 0,反之亦然。

于 2012-04-12T06:19:05.120 回答
0

据我了解TreeSet,它只能包含独特的元素。为了将这些元素存储在 中TreeSet,实现将使用该方法新元素与现有元素进行比较。compareTo()

您的代码目前在说 -人在名字上是平等的,但只能在年龄上比较

我建议您更改equals()´,compareTo() andhashCode()` 方法以考虑姓名和年龄。

要按Person年龄对您的对象进行排序,我会推荐一个ArrayList并按自定义排序Comparator

于 2012-04-12T06:23:46.040 回答
0

根据Set(其中TreeSet继承)的定义: http://docs.oracle.com/javase/6/docs/api/java/util/Set.html

集合不包含元素对 e1 和 e2 使得 e1.equals(e2)

TreeSet也必须(来自:http ://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html ):

如果要正确实现 Set 接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致

因此,您的compareTo()方法应该首先检查两个Person是否equals()通过name,如果不是,请检查它们的age.

于 2012-04-12T06:45:43.610 回答