-3

我试图了解,如何compareTo在该程序中调用该方法。

class Student implements Comparable {
    String dept, name;

    public Student(String dept, String name) {
        this.dept = dept;
        this.name = name;
    }

    public String getDepartment() {
        return dept;
    }

    public String getName() {
        return name;
    }

    public String toString() {
        return "[dept=" + dept + ",name=" + name + "]";
    }

    public int compareTo(Object obj) {
        Student emp = (Student) obj;
        System.out.println("Compare to : " +dept.compareTo(emp.getDepartment()));
        int deptComp = dept.compareTo(emp.getDepartment());

        return ((deptComp == 0) ? name.compareTo(emp.getName()) : deptComp);
    }

    public boolean equals(Object obj) {
        if (!(obj instanceof Student)) {
            return false;
        }
        Student emp = (Student) obj;
        boolean ii = dept.equals(emp.getDepartment()) && name.equals(emp.getName());
        System.out.println("Boolean equal :" +ii);
        return ii ; 

    }

    public int hashCode() {
        int i2 = 31 * dept.hashCode() + name.hashCode();
        System.out.println("HashCode :" + i2);
        return i2;

    }
}

public class CompareClass {
    public static void main(String args[]) {
        Student st[] = { new Student("Finance", "A"),
                new Student("Finance", "B"), new Student("Finance", "C"),
                new Student("Engineering", "D"),
                new Student("Engineering", "E"),
                new Student("Engineering", "F"), new Student("Sales", "G"),
                new Student("Sales", "H"), new Student("Support", "I"), };
        Set set = new TreeSet(Arrays.asList(st));
        System.out.println(Arrays.asList(st));
        System.out.println(set);
    }
}
  1. 为什么Arrays.asList(st)使用?
  2. equals()和有什么用hashcode()
4

6 回答 6

2

为什么使用 Arrays.asList(st) ?

因为TreeSet构造函数TreeSet(Collection c)接受 aCollection而不是 a String[],因此您可以使用List asList(T... a)String[]方法将 a 转换为Lista 。请注意,在这种情况下,数组与可变参数相同。Collection

equals() 和 hashcode() 有什么用?

Object 类提供了hashcode()equals()两种方法来表示对象的身份。

您在代码中使用TreeSet。根据文档

如果要正确实现 Set 接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致。(参见 Comparable 或 Comparator 以了解与 equals 一致的精确定义。)这是因为 Set 接口是根据 equals 操作定义的,但 TreeSet 实例使用其 compareTo(或 compare)方法执行所有元素比较,所以两个从集合的角度来看,这种方法认为相等的元素是相等的。

因此,在您的情况下,实现Comparable和覆盖compareTo()就足够了。


推荐阅读:

  1. 在 Java 中覆盖 equals 和 hashCode
  2. 哈希集与树集
  3. compare() 和 compareTo() 有什么区别?
于 2013-07-20T05:02:31.907 回答
1

Oracle 文档中对 Comparable 接口有很好的解释:http: //docs.oracle.com/javase/6/docs/api/java/lang/Comparable.html

在这段代码中,使用 Arrays.asList(st) 主要是因为作者认为在 Java 中实例化 Array 并将其转换为 List 比创建 ArrayList 并为每个项目调用 .add 更简单。不过,这对正在发生的事情并不重要。在同一条线上发生的另一件事是魔法所在。

Set set = new TreeSet(Arrays.asList(st));

这会从列表中创建一个 TreeSet。这篇帖子值得一看:Set和List有什么区别?简要地。在 Set 中,所有元素都是唯一的,因此当您从包含重复项的 List 创建 Set 时,Set 构造函数将丢弃额外的项目。它如何确定哪些元素是重复的?它使用 Comparable 接口的方法。类似地,List 已排序但 Set 未排序,因此实现可以选择以最有效的任何顺序将项目存储在 Set 中。在TreeSet的情况下,它在Oracle 文档的顶部轻松地解释了它是如何做到的:

请注意,如果要正确实现 Set 接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致。(参见 Comparable 或 Comparator 以了解与 equals 一致的精确定义。)这是因为 Set 接口是根据 equals 操作定义的,但 TreeSet 实例使用其 compareTo(或 compare)方法执行所有元素比较,所以两个从集合的角度来看,这种方法认为相等的元素是相等的。一个集合的行为是明确定义的,即使它的顺序与equals不一致;它只是不遵守 Set 接口的一般约定。

于 2013-07-20T05:11:22.860 回答
1

一些 Java API 是围绕数组构建的,其中一些是围绕集合构建的。asList 基本上是一个适配器,它可以让您的数组像集合一样被访问。

一些数据结构和算法对一段数据的所谓“散列”进行操作。这主要是出于性能原因。在大多数情况下,哈希是代表特定对象的单个数字。您可以看到这对于快速排序集合或检查等价性有何用处。

当然,equals 的存在是为了测试两个对象是否代表相同的事物。

于 2013-07-20T05:12:13.133 回答
1

使用 .equals() 是因为您正在比较两个对象。

于 2013-07-20T05:03:56.993 回答
1

我试图理解,如何在这个程序中调用 compareTo 方法。

因为您在这里使用的是 a TreeSet,它实现了 ,并且通过使用它们的自然顺序而不是相等SortedSet性来比较元素来计算其唯一性。

实现Comparable自身的类或自身的超类可以相互比较。对于没有的类,您可以提供 aComparator代替。

当您将元素添加到 aSortedSet时,集合将首先将其与集合中已经存在的元素进行比较,并且仅在没有比较给出 0 时才添加它。请参阅下面的演示。

另请参阅Collections.sort()

1.为什么使用Arrays.asList(st)?

因为这是 Java 1.4 代码。在 Java 5 中,您将使用Arrays.asList(s1, s2, etc)(即,可变参数方法)。

2.equals()和hashcode()有什么用?

在这种情况下,没有。


示例程序(这次使用泛型)说明 aSortedSet和 a之间的区别HashSet,使用BigDecimal

final BigDecimal one = BigDecimal.ONE;
final BigDecimal oneDotZero = new BigDecimal("1.0");

one.equals(oneDotZero); // false
one.compareTo(oneDotZero); // 0

// HashSet: uses .equals() and .hashCode();

final Set<BigDecimal> hashset = new HashSet<>();
hashset.add(one); hashset.add(oneDotZero);
hashset.size(); // 2

// TreeSet: uses Comparable

final Set<BigDecimal> treeset = new TreeSet<>();
treeset.add(one); treeset.add(oneDotZero);
treeset.size(); // 1
于 2013-07-20T05:05:53.063 回答
0

.equals 和 .hashcode 是每个类从 Java 中的 Object 类继承的方法。创建自己的类时,您通常会覆盖这两个默认实现,因为默认 Object 函数通常不会导致所需的行为。

它们确实存在很好的衡量标准,但实际上它们并没有被使用。

于 2013-07-20T05:07:28.990 回答