当整个学生对象是唯一的时,为什么 TreeSet 不能有相似的学生年龄?
Why can't TreeSet have student ages similar when the whole student object is unique?
我有一个数据类型StudentSet
。它接受姓名和年龄。当我将此添加到 TreeSet
时,不会添加年龄相似的学生。我知道 TreeSet
只添加唯一性,但我有不同的学生名字,所以总的来说 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);
}
}
更新:
罪魁祸首是我在 StudentSet
中设置了 compareTo()
方法来比较年龄,TreeSet
在内部使用它来比较和检查唯一性。
这是我更正并满意的代码。
@Override
public int compareTo(StudentSet o)
{
int i = Integer.compare(this.age, o.age);
if (i == 0)
return this.name.compareTo(o.name);
else
return i;
}
重新定义你的 compareTo
方法,StudentSet
是你自己的自定义对象,所以通过实现 Comparable
接口,你告诉编译器在你的实现之后添加到 TreeSet
.
下面的实现说,如果两个或更多 StudentSet
中的 age
相同,则它们 唯一 相等。
@Override
public int compareTo(StudentSet o)
{
return ((Integer) this.age).compareTo(o.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;
}
以上将检查两者 Age and Name
,如果相同,则您的对象是唯一的。
您正在创建 4 个 TreeSet
个实例,每个实例都有不同的 Comparator
。传递给 TreeSet
的 Comparator
确定两个元素是否被认为是相同的。
在第一个 TreeSet
中,您没有将任何 Comparator
传递给构造函数,这意味着使用了自然顺序(由 Comparable
定义)。 Comparable
的 compareTo
仅按年龄进行比较。
在第三个 TreeSet
中,您正在使用此 compare
方法:
@Override
public int compare(StudentSet o1, StudentSet o2)
{
return o1.compareTo(o2);
}
由于compareTo
只比较年龄,两个年龄相同的StudentSet
实例被认为是相同的,只有其中一个会被添加到TreeSet
。
如果您希望您的原始 set
TreeSet
以及分配给 sort
变量的 3 TreeSet
包含所有唯一元素,您的所有 compare
和 compareTo
方法必须按确定唯一 StudentSet
实例的所有属性排序。
他们可以通过每次以不同的顺序比较属性,使用不同的顺序对 TreeSet
进行排序。比如可以先比名字再比年龄(如果名字相等),也可以先比年龄再比名字(如果年龄相等)。
根据 compareTo
方法的实施,它工作正常。如果你想让它基于 name
而不是 ages
那么你需要在 compareTo
方法中更正它,如下所示,
@Override
public int compareTo(StudentSet o)
{
return this.name.compareTo(o.name);
//return ((Integer) this.age).compareTo(o.age);
}
我有一个数据类型StudentSet
。它接受姓名和年龄。当我将此添加到 TreeSet
时,不会添加年龄相似的学生。我知道 TreeSet
只添加唯一性,但我有不同的学生名字,所以总的来说 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);
}
}
更新:
罪魁祸首是我在 StudentSet
中设置了 compareTo()
方法来比较年龄,TreeSet
在内部使用它来比较和检查唯一性。
这是我更正并满意的代码。
@Override
public int compareTo(StudentSet o)
{
int i = Integer.compare(this.age, o.age);
if (i == 0)
return this.name.compareTo(o.name);
else
return i;
}
重新定义你的 compareTo
方法,StudentSet
是你自己的自定义对象,所以通过实现 Comparable
接口,你告诉编译器在你的实现之后添加到 TreeSet
.
下面的实现说,如果两个或更多 StudentSet
中的 age
相同,则它们 唯一 相等。
@Override
public int compareTo(StudentSet o)
{
return ((Integer) this.age).compareTo(o.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;
}
以上将检查两者 Age and Name
,如果相同,则您的对象是唯一的。
您正在创建 4 个 TreeSet
个实例,每个实例都有不同的 Comparator
。传递给 TreeSet
的 Comparator
确定两个元素是否被认为是相同的。
在第一个 TreeSet
中,您没有将任何 Comparator
传递给构造函数,这意味着使用了自然顺序(由 Comparable
定义)。 Comparable
的 compareTo
仅按年龄进行比较。
在第三个 TreeSet
中,您正在使用此 compare
方法:
@Override
public int compare(StudentSet o1, StudentSet o2)
{
return o1.compareTo(o2);
}
由于compareTo
只比较年龄,两个年龄相同的StudentSet
实例被认为是相同的,只有其中一个会被添加到TreeSet
。
如果您希望您的原始 set
TreeSet
以及分配给 sort
变量的 3 TreeSet
包含所有唯一元素,您的所有 compare
和 compareTo
方法必须按确定唯一 StudentSet
实例的所有属性排序。
他们可以通过每次以不同的顺序比较属性,使用不同的顺序对 TreeSet
进行排序。比如可以先比名字再比年龄(如果名字相等),也可以先比年龄再比名字(如果年龄相等)。
根据 compareTo
方法的实施,它工作正常。如果你想让它基于 name
而不是 ages
那么你需要在 compareTo
方法中更正它,如下所示,
@Override
public int compareTo(StudentSet o)
{
return this.name.compareTo(o.name);
//return ((Integer) this.age).compareTo(o.age);
}