首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么当Comparator.compare变得相等时我们需要返回0

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

Stack Overflow用户
提问于 2019-10-07 10:42:19
回答 3查看 6.8K关注 0票数 3

我知道在实现比较器接口的比较方法时,我们需要返回。

  • +1 if o1 > o2
  • -1如果o1 < o2
  • 0如果o1 == o2

我的问题是,当两者相等时,为什么我们需要返回0?用例是什么,或者在哪里使用?如果我们考虑排序时,o2大于o1或o2等于o1,则不更改它的位置。有人能来解释一下这方面的实际用例吗?

Java文档说

比较它的两个排序参数。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数。

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

零,或正整数

代码语言:javascript
运行
复制
 @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;
        }

    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-10-07 11:24:28

在排序时,-1和对排序列表的排序有着非常相似的影响,因为compareTo值为0的项将被分组在一起。

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

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

代码语言:javascript
运行
复制
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;
  }
}

在这里,我们已经重写了图书的compareTo,以创建一个自定义比较,首先检查图书isbn,然后检查它的标题。

比方说,你有一个图书馆,里面有书。您可能希望阻止用户在该图书馆中添加复制图书.

代码语言:javascript
运行
复制
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;
        }
    }
  }
}
票数 6
EN

Stack Overflow用户

发布于 2019-10-07 10:48:25

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

这就是为什么compare的总合同要求:

代码语言:javascript
运行
复制
sign(compare(f1,f2)) = -sign(compare(f2,f1))

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

票数 6
EN

Stack Overflow用户

发布于 2019-10-07 11:19:35

您可以使用以下实现来考虑二进制搜索算法

代码语言:javascript
运行
复制
function binary_search(A, n, T):
    L := 0
    R := n − 1
    while L <= R:
        m := floor((L + R) / 2)
        if A[m] < T:
            L := m + 1
        else if A[m] > T:
            R := m - 1
        else:
            return m
    return unsuccessful

假设有一个Comapator,它为相等和较少的情况返回相同的值:

代码语言:javascript
运行
复制
public int compare(Test f1, Test f2) {
        if (f1.getId() > f2.getId()) {
            return 1;
        } else {
            return -1; 
}

现在A[m] < TA[m].compareTo(T) < 0,将是true,当T等于A[m]时,当A[m]小于T时。

因此,在这种情况下:

代码语言:javascript
运行
复制
1 2 3 4 // array and A[m] is 2
2 // target T

2.compareTo(2)返回-1,它使算法转到下一个执行L = m + 1 ->,而不是返回正确的值。

事实上,二进制搜索将陷入不定式循环,从2.compareTo(2)3.compareTo(2)跳过。我希望这能帮到你。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58267950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档