Java 为什么可以';当整个学生对象是唯一的时,t树集是否具有相似的学生年龄?

Java 为什么可以';当整个学生对象是唯一的时,t树集是否具有相似的学生年龄?,java,set,treeset,Java,Set,Treeset,我有一个数据类型StudentSet。它接受名字和年龄。当我将其添加到树集时,不会添加年龄相似的学生。我知道TreeSet只添加了unique,但我对学生有不同的名字,所以作为一个整体,StudentSet不是唯一的吗?我想知道这背后的原因 下面是我的代码 import java.util.Comparator; import java.util.TreeSet; public class StudentSet implements Comparable<StudentSet> {

我有一个数据类型
StudentSet
。它接受名字和年龄。当我将其添加到
树集
时,不会添加年龄相似的学生。我知道
TreeSet
只添加了unique,但我对学生有不同的名字,所以作为一个整体,
StudentSet
不是唯一的吗?我想知道这背后的原因

下面是我的代码

import java.util.Comparator;
import java.util.TreeSet;

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

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

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


    public static void main(String[] args) {
        TreeSet<StudentSet> set = new TreeSet<>();
        set.add(new StudentSet("xyz", 21));
        set.add(new StudentSet("abc", 23));
        set.add(new StudentSet("xyxyxr", 24));
        System.out.println(set.add(new StudentSet("aaaaaa", 20))); //prints false
        System.out.println(set.add(new StudentSet("bbbbbb", 20))); //prints false
        System.out.println(set.add(new StudentSet("cccc", 20))); //prints false

        TreeSet<StudentSet> sort = new TreeSet<>(new Comparator<StudentSet>() {
            @Override
            public int compare(StudentSet o1, StudentSet o2) {
                return o1.name.compareTo(o2.name);
            }
        });

        sort.addAll(set);
        System.out.println("Sorting According to Name\n");
        for (StudentSet s : sort) {
            System.out.println(s);
        }
        System.out.println();

        sort = new TreeSet<>(new Comparator<StudentSet>() {
            @Override
            public int compare(StudentSet o1, StudentSet o2) {
                return o1.compareTo(o2);
            }
        });

        System.out.println("Sorting According to Age\n");
        sort.addAll(set);
        for (StudentSet s : sort) {
            System.out.println(s);
        }
        System.out.println();

        sort = new TreeSet<>(new Comparator<StudentSet>() {
            @Override
            public int compare(StudentSet o1, StudentSet o2) {
                int lastIndex1 = o1.name.lastIndexOf(" ");
                int lastIndex2 = o2.name.lastIndexOf(" ");

                String lastName1 = o1.name.substring(lastIndex1);
                String lastName2 = o2.name.substring(lastIndex2);
                if (lastName1.equals(lastName2)) {
                    return o1.name.compareTo(o2.name);
                } else {
                    return lastName1.compareTo(lastName2);
                }
            }
        });

        System.out.println("Sorting According to Last Name\n");
        sort.addAll(set);
        for (StudentSet s : sort) {
            System.out.println(s);
        }
    }

    @Override
    public int compareTo(StudentSet o) {
        return ((Integer) this.age).compareTo(o.age);
    }
}

重新定义
compareTo
方法,
StudentSet
是您自己的自定义对象,因此通过实现
Comparable
接口,您告诉编译器在实现后添加到
TreeSet

下面的实现表示,如果两个或多个
StudentSet
age
是相同的,那么它们是唯一相等的

修改实现如下:

@Override
    public int compareTo(StudentSet o)
    {
         int i = ((Integer) this.age).compareTo(o.age);
            if (i == 0)
                return this.name.compareTo(o.name);
            else
               return i;
    }

上面将检查
年龄和姓名,如果相同,则对象是唯一的。

您正在创建4个
树集
实例,每个实例都有一个不同的
比较器
。传递到
树集的
比较器
确定两个元素是否相同

在第一个
树集
中,您没有将任何
比较器
传递给构造函数,这意味着使用了自然排序(由
可比
定义)。
compariable
comparieto
仅按年龄进行比较

在第三个
树集
中,您正在使用此
比较
方法:

    @Override
    public int compare(StudentSet o1, StudentSet o2)
    {
        return o1.compareTo(o2);
    }
由于
compareTo
仅按年龄进行比较,因此具有相同年龄的两个
StudentSet
实例被视为相同,并且只有一个实例将添加到
树集

如果希望原始
集合
树集
以及分配给
排序
变量的3个
树集
包含所有唯一元素,则所有
比较
比较到
方法必须按确定唯一
学生集
实例的所有属性进行排序


他们可以通过每次以不同的顺序比较属性,使用不同的顺序对
树集进行排序。例如,一个可以先比较姓名,然后比较年龄(如果姓名相等),而另一个可以先比较年龄,然后比较姓名(如果年龄相等)。

根据
compareTo
方法的实现,它工作正常。如果希望它基于
名称
而不是
年龄
,则需要在
比较
方法中更正此问题,如下所示:

@Override
public int compareTo(StudentSet o)
{
    return this.name.compareTo(o.name);
    //return ((Integer) this.age).compareTo(o.age);
}

您的
compareTo
方法只使用
age
作为对象比较和唯一性的参数。请阅读
TreeSet
javadoc。它说元素通过使用
比较器被认为是相等的(或者
比较
,如果使用
比较器
),谢谢大家。所以我必须从最初的StudentSet类中删除比较器?@ShubhamKharde有任何解决方案适合你。是的。谢谢你清除了@ankur singhal。我不知道实现比较器也是对uniqueness@ShubhamKharde已更正,如果有任何其他错误,请更正并标记为您应该使用的答案,这样您就不必强制转换为
整数
inti=Integer.compare(this.age,o.age)@maba建议进行良好的更改,编辑已接受,请进行更改。这将再次出现问题,无法在TreeSet中添加相似的名称但不同的年龄。此比较器用于TreeSet类中的唯一性测试。请参阅我在ankur所学答案中的修改
    @Override
    public int compare(StudentSet o1, StudentSet o2)
    {
        return o1.compareTo(o2);
    }
@Override
public int compareTo(StudentSet o)
{
    return this.name.compareTo(o.name);
    //return ((Integer) this.age).compareTo(o.age);
}