为什么Java类可以实现可比性?

时间:2010-09-15 14:04:05

标签: java

为什么使用Java Comparable?为什么有人在课堂上实施Comparable?您需要实施可比较的实际例子是什么?

10 个答案:

答案 0 :(得分:200)

这是一个现实生活中的样本。请注意,String也会实现Comparable

class Author implements Comparable<Author>{
    String firstName;
    String lastName;

    @Override
    public int compareTo(Author other){
        // compareTo should return < 0 if this is supposed to be
        // less than other, > 0 if this is supposed to be greater than 
        // other and 0 if they are supposed to be equal
        int last = this.lastName.compareTo(other.lastName);
        return last == 0 ? this.firstName.compareTo(other.firstName) : last;
    }
}

后..

/**
 * List the authors. Sort them by name so it will look good.
 */
public List<Author> listAuthors(){
    List<Author> authors = readAuthorsFromFileOrSomething();
    Collections.sort(authors);
    return authors;
}

/**
 * List unique authors. Sort them by name so it will look good.
 */
public SortedSet<Author> listUniqueAuthors(){
    List<Author> authors = readAuthorsFromFileOrSomething();
    return new TreeSet<Author>(authors);
}

答案 1 :(得分:36)

可比较定义了自然顺序。这意味着当一个对象被认为是“小于”或“大于”时,你就是在定义它。

假设您有一堆整数,并且想要对它们进行排序。这很简单,只需将它们放入已排序的集合中,对吧?

TreeSet<Integer> m = new TreeSet<Integer>(); 
m.add(1);
m.add(3);
m.add(2);
for (Integer i : m)
... // values will be sorted

但现在假设我有一些自定义对象,其中排序对我有意义,但未定义。比方说,我有按人口密度的邮政编码表示区域的数据,我想按密度对它们进行排序:

public class District {
  String zipcode; 
  Double populationDensity;
}

现在最简单的排序方法是通过实现Comparable以自然顺序定义它们,这意味着这些对象被定义为有序的标准方式。:

public class District implements Comparable<District>{
  String zipcode; 
  Double populationDensity;
  public int compareTo(District other)
  {
    return populationDensity.compareTo(other.populationDensity);
  }
}

请注意,您可以通过定义比较器来执行相同的操作。不同之处在于比较器定义了对象之外的排序逻辑。也许在一个单独的过程中,我需要通过zipcode订购相同的对象 - 在这种情况下,排序不一定是对象的属性,或者与对象的自然顺序不同。您可以使用外部比较器来定义整数的自定义排序,例如通过按字母顺序排序它们。

基本上,排序逻辑必须存在于某个地方。那可以是 -

  • 在对象本身中,如果它自然具有可比性(扩展Comparable -e.g.整数)

  • 在外部比较器中提供,如上例所示。

答案 2 :(得分:14)

引自javadoc;

  

这个界面强加了一个   对每个类的对象进行排序   实现它。这个顺序是   被称为班级的自然   订购,以及班级的比较   方法被称为其自然   比较法。

     

列出(和数组)对象   实现此接口可以进行排序   由Collections.sort自动生成(和   Arrays.sort)。实现的对象   此接口可用作键   有序地图或作为元素   排序集,无需   指定一个比较器。

编辑:..并使重要的位变得粗体。

答案 3 :(得分:8)

类实现Comparable这一事实意味着您可以从该类中获取两个对象并进行比较。有些类,比如某些集合(集合中的排序函数),它们保持对象的顺序依赖于它们是可比较的(为了排序,你需要知道哪个对象是“最大的”等等)。

答案 4 :(得分:7)

上面的大多数示例都展示了如何在compareTo函数中重用现有的可比较对象。如果你想比较同一个类的两个对象,你想要实现你自己的compareTo,比如你想要按价格排序的AirlineTicket对象(较少排在第一位),然后是中途停留次数(再次,较少是排名第一),你会做以下事情:

class AirlineTicket implements Comparable<Cost>
{
    public double cost;
    public int stopovers;
    public AirlineTicket(double cost, int stopovers)
    {
        this.cost = cost; this.stopovers = stopovers ;
    }

    public int compareTo(Cost o)
    {
        if(this.cost != o.cost)
          return Double.compare(this.cost, o.cost); //sorting in ascending order. 
        if(this.stopovers != o.stopovers)
          return this.stopovers - o.stopovers; //again, ascending but swap the two if you want descending
        return 0;            
    }
}

答案 5 :(得分:6)

实现多个字段比较的简单方法是使用Guava's ComparisonChain - 然后您可以说

   public int compareTo(Foo that) {
     return ComparisonChain.start()
         .compare(lastName, that.lastName)
         .compare(firstName, that.firstName)
         .compare(zipCode, that.zipCode)
         .result();
   }

而不是

  public int compareTo(Person other) {
    int cmp = lastName.compareTo(other.lastName);
    if (cmp != 0) {
      return cmp;
    }
    cmp = firstName.compareTo(other.firstName);
    if (cmp != 0) {
      return cmp;
    }
    return Integer.compare(zipCode, other.zipCode);
  }
}

答案 6 :(得分:3)

例如,当您想要排序的集合或map

答案 7 :(得分:2)

Comparable用于比较班级的实例。我们可以从多种方式比较实例,这就是为什么我们需要实现方法compareTo以了解我们想要比较实例的方式(属性)。

Dog class:

package test;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        Dog d1 = new Dog("brutus");
        Dog d2 = new Dog("medor");
        Dog d3 = new Dog("ara");
        Dog[] dogs = new Dog[3];
        dogs[0] = d1;
        dogs[1] = d2;
        dogs[2] = d3;

        for (int i = 0; i < 3; i++) {
            System.out.println(dogs[i].getName());
        }
        /**
         * Output:
         * brutus
         * medor
         * ara
         */

        Arrays.sort(dogs, Dog.NameComparator);
        for (int i = 0; i < 3; i++) {
            System.out.println(dogs[i].getName());
        }
        /**
         * Output:
         * ara
         * medor
         * brutus
         */

    }
}

Main class:

package test;

import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        Dog d1 = new Dog("brutus");
        Dog d2 = new Dog("medor");
        Dog d3 = new Dog("ara");
        Dog[] dogs = new Dog[3];
        dogs[0] = d1;
        dogs[1] = d2;
        dogs[2] = d3;

        for (int i = 0; i < 3; i++) {
            System.out.println(dogs[i].getName());
        }
        /**
         * Output:
         * brutus
         * medor
         * ara
         */

        Arrays.sort(dogs, Dog.NameComparator);
        for (int i = 0; i < 3; i++) {
            System.out.println(dogs[i].getName());
        }
        /**
         * Output:
         * ara
         * medor
         * brutus
         */

    }
}

以下是如何在Java中使用可比较的好例子:

http://www.onjava.com/pub/a/onjava/2003/03/12/java_comp.html?page=2

答案 8 :(得分:2)

实施Comparable接口时,需要实现方法compareTo()。您需要它来比较对象,以便使用例如ArrayList类的排序方法。您需要一种比较对象的方法,以便对它们进行排序。因此,您需要在类中使用自定义compareTo()方法,以便将其与ArrayList排序方法一起使用。 compareTo()方法返回-1,0,1。

我刚刚阅读了Java Head 2.0的相关章节,我还在学习。

答案 9 :(得分:1)

好的,但为什么不在没有实现类似接口的情况下定义<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/> <link href="https://netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet"/> <div class="panel-group" id="accordion"> <div class="panel panel-default" id="panel1"> <div class="panel-heading"> <h4 class="panel-title"> <a data-toggle="collapse" data-target="#collapseOne" href="#collapseOne"> Collapsible Group Item #1 </a> </h4> </div> <div id="collapseOne" class="panel-collapse collapse in"> <div class="panel-body"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean consequat eget leo vel condimentum. In dignissim sed nunc et malesuada. Etiam elit lacus, auctor sed mi sed, luctus convallis augue. Aenean tristique eu magna eu sodales. Sed sit amet enim ut quam tincidunt consectetur vitae eu purus. Sed lectus turpis, gravida sit amet arcu id, malesuada ornare nisl. Sed dignissim quam non tellus congue vestibulum non vel turpis. Fusce vehicula augue lacinia felis mattis, quis ultricies ex faucibus. Nulla quis arcu a nunc pulvinar egestas ac elementum elit. Morbi ultricies condimentum fermentum. Vivamus a purus dui. Suspendisse nulla arcu, molestie sed cursus et, luctus id quam. Donec enim est, consequat vel luctus vitae, fringilla id tortor. Nullam eget justo malesuada, porttitor mauris sit amet, luctus quam. </div> </div> </div> </div>方法。 例如,由compareTo()City以及

定义的班级name
temperature