Java Comparable接口详细介绍

x33g5p2x  于2021-08-20 转载在 Java  
字(5.0k)|赞(0)|评价(0)|浏览(511)

我们知道,比较原始值如int、char、float是非常容易的,可以用比较运算符如<、>、==等来完成。

但是比较对象就有点不同了。例如,你如何比较两个雇员?你如何比较两个学生?
你需要明确地定义用户定义的类的对象应该如何比较。为此,Java提供了两个接口,叫做Comparable和Comparator。
在本指南中,我们将通过实例来详细介绍Comparable Interface。

1. 我们将学到什么?

  • 可比接口的概述
  • 以升序排列用户定义的对象。
    以降序排列用户定义的对象 * 以降序排列用户定义的对象
  • 排序字符串和封装类
  • 更多的例子

2. ComparableInterface的概述

默认情况下,一个用户定义的类是不可比较的。也就是说,它的对象不能被比较。要使一个对象具有可比性,该类必须实现可比较接口。

Comparableinterface有一个叫做compareTo()的方法,你需要实现这个方法,以便定义一个对象与所提供的对象进行比较。

public interface Comparable<T> {
     public int compareTo(T o);
}

当你在你的类中定义compareTo()方法时,你需要确保这个方法的返回值是。

  • 负值,如果这个对象小于提供的对象。
  • 零,如果这个对象等于提供的对象。
  • 正数,如果这个对象大于提供的对象。许多预定义的Java类,如String、Date、LocalDate、LocalDateTime等,都实现了Comparable接口来定义其实例的排序。
    ComparableInterface为一个类的对象提供了默认的排序。这个默认排序也被称为对象的自然排序。 

例如,如果列表由Stringe元素组成,它将被排序为字母顺序。如果它由Date元素组成,它将被排序为按时间顺序排列。这是怎么发生的呢?String和Dat都实现了Comparable接口。 
可比接口的实现为一个类提供了一个自然的排序,这使得该类的对象可以被自动排序。

让我们看看如何在一个用户定义的类中实现可比较界面,并定义compareTo()方法,使该类的对象具有可比性。

3. 对用户定义的对象按升序排序

这个例子表明,我们创建了一个人的对象列表,并通过使用ComparableInterface的compateTo()方法来比较每个人的年龄。

简而言之,我们是按年龄升序对人进行排序。

public class Person implements Comparable<Person> {

 private int id;

 private String name;

 private int age;

 public Person(int id, String name, int age) {
  this.id = id;
  this.name = name;
  this.age = age;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 @Override
 public String toString() {
  return this.name;
 }

 @Override
 public int compareTo(Person otherPerson) {
  return (this.getAge() - otherPerson.getAge());
 }
}
import java.util.ArrayList;

import java.util.Collections;
import java.util.List;

public class PersonSorterInASC {
 public static void main(String[] args) {

  sortUserDefinedObjectsInAsc();
 }

 private static void sortUserDefinedObjectsInAsc() {
  List<Person> persons = new ArrayList<Person>();
  Person person1 = new Person(59, "John", 40);
  Person person12 = new Person(67, "Roger", 25);
  Person person13 = new Person(45, "Steven", 30);
  persons.add(person1);
  persons.add(person12);
  persons.add(person13);

  System.out.println("Before Sorting : " + persons);
  Collections.sort(persons);
  System.out.println("After Sorting : " + persons);
 }
}

输出:

Before Sorting : [John, Roger, Steven]
After Sorting : [Roger, Steven, John]

4. 对用户定义的对象按降序排序

Java在构建时提供了sort()和Collections.reverseOrder()的实用方法来对对象进行降序排序。

Collections.reverseOrder()

返回一个比较器,对实现了可比较界面的对象集合进行自然排序的反向排序。

Collections.sort(persons, Collections.reverseOrder());

这个例子表明,我们正在按年龄降序对人的对象进行排序。

public class PersonSorterInDESC {

 public static void main(String[] args) {
  sortUserDefinedObjectsinDesc();
 }
 
 private static void sortUserDefinedObjectsinDesc(){
  List<Person> persons = new ArrayList<Person>();
  Person person1 = new Person(59, "John", 40);
  Person person12 = new Person(67, "Roger", 25);
  Person person13 = new Person(45, "Steven", 30);
  persons.add(person1);
  persons.add(person12);
  persons.add(person13);

  System.out.println("Before Sorting : " + persons);
  Collections.sort(persons, Collections.reverseOrder());
  
  System.out.println(" Sort in decending order : " + persons);

 }
}

输出:

Before Sorting : [John, Roger, Steven]
Sort in decending order : [John, Steven, Roger]

5. 对String和Wrapper类进行排序

让我们看看对String和Wrapper类的排序,因为这些类在内部实现了Comparable接口。

5.1 对Stringobjects进行排序

List<String> names = new ArrayList<>();
names.add("ABC");
names.add("ACB");
names.add("PQR");
names.add("CDQ");

System.out.println("Before Sorting : " + names);
Collections.sort(names);
System.out.println("After Sorting : " + names);

输出

Before Sorting : [ABC, ACB, PQR, CDQ]
After Sorting : [ABC, ACB, CDQ, PQR]

5.2 对封装器类对象进行排序

List<Integer> names = new ArrayList<>();
names.add(100);
names.add(20);
names.add(10);
names.add(50);

System.out.println("Before Sorting : " + names);
Collections.sort(names);
System.out.println("After Sorting : " + names);

输出。

Before Sorting : [100, 20, 10, 50]
After Sorting : [10, 20, 50, 100]

6. 更多的例子

下面这个代表一个人的名字的类实现了可比较性

public class Name implements Comparable<Name> {
    private final String firstName, lastName;

    public Name(String firstName, String lastName) {
        if (firstName == null || lastName == null)
            throw new NullPointerException();
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String firstName() { return firstName; }
    public String lastName()  { return lastName;  }

    public boolean equals(Object o) {
        if (!(o instanceof Name))
            return false;
        Name n = (Name) o;
        return n.firstName.equals(firstName) && n.lastName.equals(lastName);
    }

    public int hashCode() {
        return 31/*firstName.hashCode() + lastName.hashCode();
    }

    public String toString() {
 return firstName + " " + lastName;
    }

    public int compareTo(Name n) {
        int lastCmp = lastName.compareTo(n.lastName);
        return (lastCmp != 0 ? lastCmp : firstName.compareTo(n.firstName));
    }
}

下面是一个建立姓名列表并对其进行排序的程序。

public class NameSort {
    public static void main(String[] args) {
        Name nameArray[] = {
            new Name("John", "Smith"),
            new Name("Karl", "Ng"),
            new Name("Jeff", "Smith"),
            new Name("Tom", "Rich")
        };

        List<Name> names = Arrays.asList(nameArray);
        Collections.sort(names);
        System.out.println(names);
    }
}

如果你运行这个程序,下面是它的打印结果。

[Karl Ng, Tom Rich, Jeff Smith, John Smith]

相关文章