我正在尝试从TreeSet中删除最老的Student,但是该对象没有被删除。有人可以解释一下如何从我的TreeSet中删除最旧的Student对象吗?
public class Student implements Comparable<Student> {
private String studentId;
private String studentAge;
public Student(String studentId, String studentAge) {
super();
this.studentId = studentId;
this.studentAge = studentAge;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentAge() {
return studentAge;
}
public void setStudentAge(String studentAge) {
this.studentAge = studentAge;
}
@Override
public int compareTo(Student o) {
if (Double.valueOf(studentAge).compareTo(Double.valueOf(o.getStudentAge())) == 0) {
return 1;
} else
return Double.valueOf(studentAge).compareTo(Double.valueOf(o.getStudentAge()));
}
@Override
public boolean equals(Object obj) {
Student student = (Student) obj;
return (student.getStudentId().equals(studentId) && student.getStudentAge().equals(studentAge));
}
@Override
public String toString() {
return "StudentId " + studentId + " Student Age " + studentAge;
}
}
import java.util.TreeSet;
public class MainApp {
public static void main(String[] args) {
TreeSet<Student> studentList = new TreeSet<Student>();
studentList.add(new Student("10001", "5"));
studentList.add(new Student("10001", "15"));
studentList.add(new Student("10001", "25"));
studentList.add(new Student("10001", "3"));
studentList.add(new Student("10001", "2"));
studentList.add(new Student("10001", "1"));
studentList.add(new Student("10001", "10"));
studentList.add(new Student("10001", "6"));
studentList.add(new Student("10001", "7"));
studentList.add(new Student("10001", "2"));
System.out.println(studentList.last().getStudentAge());
System.out.println(studentList);
Student maxAge = studentList.last();
System.out.println(studentList.remove(new Student(maxAge.getStudentId(), maxAge.getStudentAge())));
System.out.println(studentList);
}
}
答案 0 :(得分:2)
您的compare方法被简单地说成是错误的。
第一个天真的解决方法:将两个年龄值提取为数字(并使用整数,因为年龄似乎总是以整数形式出现)。然后打电话
return Integer.compare(first, second);
仅。 (也许您将不得不改变这两个值,具体取决于您希望对集合进行排序的方式)
您当前在值相等时返回1的方法只是假的。
要点是:TreeSet无法正确排序元素,因为您的compareTo()
方法在逻辑上已损坏。排序工作完成后,您可以轻松识别集合中的第一个或最后一个元素并将其删除。
但是真正的问题是:您的基础设计是错误的。您会看到,当您有equals()
和compareTo()
时,人们很快就会谈论:平等努力是否应该为compareTo()
赋予0?可以归结为:哪些数据输入到您的equals()
方法中。想想看:年龄是否对两个人的身份相同?否。您有一个学生 ID 。 ID的性质用于唯一地识别事物。因此:您应该首先真正弄清组成“独特”学生的原因。
我的建议:
Comparator<Student>
实例。您可以有一个比较器,将两个学生与上升年龄进行比较。还有另一个带有降序。这是关键点:仅当您具有真正的“自然”排序顺序(例如Integer)时,才使用Comparable。但是人,学生:对它们进行排序取决于上下文如何。也许随着年龄的增长。但是也许以后您添加一个名称,然后您想要对这些名称字符串进行排序。
答案 1 :(得分:2)
正如其他人所说,您的compareTo
方法是错误的。当两个实例相等时,永远不要返回1
。这是一个小问题。话虽如此,您的compareTo
方法是错误的,不仅因为这个原因,而且还因为您正在根据学生的年龄比较他们。 TreeSet
是Set
,并且集合不能有重复的元素,因此,这意味着您的集合将无法容纳具有相同元素的学生年龄。
幸运的是,每个学生都有一个唯一的ID,因此您可以使用此ID断开联系(即,当两个学生的年龄相同时),从而使两个实例的{em> 与{{1 }}方法,即使它们的年龄相同:
compareTo
注意:这是假设年龄为@Override
public int compareTo(Student o) {
int result = Integer.compare(studentAge, o.getStudentAge());
return result == 0 ? studentId.compareTo(o.getStudentId()) : result;
}
类型。
现在,一旦您固定了int
方法,就可以安全地使用compareTo
的查找方法。要从您的TreeSet
中删除最老的学生,您可以使用pollLast
方法,该方法正是您想要的:
TreeSet
答案 2 :(得分:1)
很少有观察结果,如果得到纠正,将解决问题。
-为什么年龄为String?请使其为整数或双精度。在这种情况下,您的compareTo方法将是
@Override
public int compareTo(Student o) {
return this.studentAge.compareTo(o.getStudentAge());
}
-如果您仍然希望使用age作为String,请使用下面的compareTo方法。
@Override
public int compareTo(Student o) {
return Double.valueOf(studentAge).compareTo(Double.valueOf(o.getStudentAge()));
}
这两种方法都可以解决您的问题。
现在说明: 与其他映射不同(因为集仅是内部映射,希望您知道),所以不会基于equals方法比较键。如果实现了Comparable或Compartor实现,则根据compareTo比较密钥。 由于您的compareTo方法有问题,因此调用remove方法时永远不会找到25岁的学生。
调用remove方法时,它将尝试使用年龄来搜索键,但是由于您的比较从技术上讲永远不会返回0(表示相等),因此永远不会找到对象,因此也不会删除对象。
但是最后一个方法给出了正确的学生值,因为在填充值的情况下compareTo方法将正常工作。.
答案 3 :(得分:0)
建议,equals
方法在覆盖..p时应考虑以下条件。
instanceof
运算符来实现。添加了String
类equals
方法供参考
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}