0

题目描述

题目来源及自己的思路

我的程序里声明了一个 TreeSet 对象 ts,写了一个学生类,当学生的年龄和姓名相同时被认为是相同元素。在 ts 中添加了第一个学生对象与最后一个学生对象时,使这俩个学生对象的姓名和年龄相同,打印结果发现这俩个元素均被输出,ts 大小为 4。

相关代码

import java.util.TreeSet;
public class TreeSetDemo {

public static void main(String[] args) {
    TreeSet<Student> ts = new TreeSet<>();
    ts.add(new Student("lisi02", 22));
    ts.add(new Student("lisi01", 40));
    ts.add(new Student("lisi08", 19));
    ts.add(new Student("lisi02", 22));


    // the first element and the last one are added to ts
    // However, ts belongs to a Set Collection.
    // So I think the last one should not be added to ts.
    // when the second element is annotated, the last one can not be added.
    // Can you explain why?
    
    for (Student e : ts) {
        System.out.println(e.getName() + "\t...\t" + e.getAge());
    }
    System.out.println(ts.size());
}

}

class Student implements Comparable {

private String name;
private int age;
Student(String name, int age) {
    this.name = name;
    this.age = age;
}

public String getName() {
    return name;
}

public int getAge() {
    return age;
}

public int compareTo(Object obj) {
    if (!(obj instanceof Student))
        throw new RuntimeException("Not Student class");
    Student p = (Student) obj;

    // When name and age are the same, the elements are the same
    if (this.name.equals(p.getName()) && p.getAge() == this.age) {
        System.out.println(name + "..." +age);
        return 0;
    } else
        return 1;
}

}

你期待的结果是什么?实际看到的错误信息又是什么?

2019-01-11 提问

查看全部 3 个回答

1

哪里来的相同元素?判断元素是否相同需要实现hashCodeequals方法,很明显你没有实现,所以第一个元素和最后一个元素是不同的元素,Comparable是用来比较大小的,是用来排序的。就好比一辆货车和一辆卡车可以比较大小,但是他们是相同的吗?

推荐答案

2

已采纳
  1. 你的 compareTo 方法返回 01,返回 0 的时候新 value 替换旧 value,
    返回 1 的时候,则作为子节点添加到红黑树的右边。
  2.  ts.add(new Student("lisi02", 22));
     ts.add(new Student("lisi01", 40));
     ts.add(new Student("lisi08", 19));
     ts.add(new Student("lisi02", 22));

    如果代码是这样的,当你添加完第三个元素 lisi08 19 的时候,红黑树会进行旋转操作,旋转完 root 节点是 lisi01 40,左子节点为 lisi02 22,右子节点为 lisi08 19,当你添加第四个元素时候,只会和 lisi01 40lisi08 19 进行比较,因为你的 compareTo 方法不存在 -1 的返回值。所以 ts 中会保存第四个元素。

  3.  ts.add(new Student("lisi02", 22));
     // ts.add(new Student("lisi01", 40));
     ts.add(new Student("lisi08", 19));
     ts.add(new Student("lisi02", 22));

    当你把第二个元素注释掉,添加完 lisi02 22lisi08 19 之后,红黑树不需要旋转,root 节点是 lisi02 22,右子节点为 lisi08 19,当你添加最后一个 lisi02 22 的时候是会和第一个 lisi02 22进行比较的。所以 ts 中只会有两个元素。

推广链接