为什么当Comparator.compare相等时我们需要返回0

Der*_*ble 2 java sorting collections comparator

我了解在执行Comparator接口的比较方法时,我们需要返回

  • 如果o1> o2,则+1
  • 如果o1 <o2则为-1
  • 如果o1 == o2,则为0

我的问题是为什么我们都必须在相等时返回0?用例是什么?用在什么地方?如果我们考虑在o2大于o1或o2等于o1时进行排序,则不会更改其位置。谁能来解释这个的实际用例?

Java文档说

比较其两个参数的顺序。当第一个参数小于,等于或大于第二个参数时,返回负整数,零或正整数。

这是否意味着返回-1或返回0具有相同的影响?

零或正整数

 @Override
    public int compare(Test f1, Test f2) {
        if (f1.getId() > f2.getId()) {
            return 1;
        } else if (f1.getId() < f2.getId()) {
            return -1;
        } else {
            return 0;
        }

    }
Run Code Online (Sandbox Code Playgroud)

Era*_*ran 6

如果您返回比较的两个值时-1相等,compare(f1,f2)compare(f2,f1)都将返回-1。这意味着您的元素顺序将不一致。它可能会破坏某些排序算法。

因此,的总合同compare要求:

sign(compare(f1,f2)) = -sign(compare(f2,f1))
Run Code Online (Sandbox Code Playgroud)

这意味着当两个值相等时必须返回0。

  • @DerekNoble你问为什么当f1和f2的值相等时必须返回0。因此我解释说,如果你不返回 0(例如,返回 -1),那么 `compare(f1,f2)` 和 `compare(f2,f1)` 都将返回 -1 (2认同)

Amb*_*o-r 5

当您进行排序时,-10对排序列表的排序具有非常相似的影响,因为其中compareTo评估为 0 的项目将被组合在一起。

您将“实际上”在其他场景中使用此比较,例如您可能不想重复将复杂对象添加到列表的情况(是的,您也可以通过使用 a 来实现此场景set)。

假设我们有一个对象Book如下:

import java.util.Comparator;

public class Book implements Comparable {

  String isbn;
  String title;

  public Book(String id, String title) {
    this.isbn = id;
    this.title = title;
  }

  String getIsbn() {
    return isbn;
  }

  String getTitle() {
    return title;
  }

  @Override
  public int compareTo(Object o) {
    return Comparator
            .comparing(Book::getIsbn)
            .thenComparing(Book::getTitle)
            .compare(this, (Book) o);
  }

  @Override
  public  String toString() {
    String output = new StringBuilder()
            .append(isbn).append(":").append(title)
            .toString();
    return output;
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们覆盖了compareToof book 以创建一个自定义比较,首先检查书籍 isbn 然后它的标题。

假设(例如)你有一个图书馆,里面有书。您可能希望阻止您的用户在该图书馆中添加重复的书籍......

public class Library {

  public static void main(String [] args) {
    List<Book> library = new ArrayList<>();
    library.add(new Book("9780593098240", "Children of Dune"));
    library.add(new Book("9780593098233", "Dune Messiah"));
    library.add(new Book("9780441172719", "Dune"));
    // Just to show the sorting, based on multiple attributes.
    Collections.sort(library);
    System.out.println("Books in library: " + Arrays.toString(library.toArray()));

    // You would obviously have some code for entering a book here, but easier to just create the object for an example. 
    Book newBook = new Book("9780593098240", "Children of Dune");
    for (Book bookInLibrary : library) {
        if (bookInLibrary.compareTo(newBook) == 0) {
            System.out.println("We already have that book in the library.");
            break;
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 只有某些稳定的排序算法才会将负值和“0”视为相同。它可能与其他算法有不同的处理方式。除此之外,您复制了 OP 的错误,假设比较器必须返回“-1”、“0”或“+1”之一。比较器可以返回*任何* int 值,如果非零,则仅符号重要。 (2认同)