Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当Comparator.compare变为相等时,为什么需要返回0_Java_Sorting_Collections_Comparator - Fatal编程技术网

Java 当Comparator.compare变为相等时,为什么需要返回0

Java 当Comparator.compare变为相等时,为什么需要返回0,java,sorting,collections,comparator,Java,Sorting,Collections,Comparator,我知道在实现比较器接口的比较方法时,我们需要返回 +如果o1>o2,则为1 -如果o1f2.getId()){ 返回1; }else if(f1.getId()

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

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

Java文档说

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

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

零或正整数

@覆盖
公共整数比较(测试f1、测试f2){
if(f1.getId()>f2.getId()){
返回1;
}else if(f1.getId()
如果在比较的两个值相等时返回-1,
compare(f1,f2)
compare(f2,f1)
都将返回
-1
。这意味着元素的顺序将不一致。它可以破坏一些排序算法

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

sign(compare(f1,f2)) = -sign(compare(f2,f1))
这意味着您必须在两个值相等时返回0。

您可以考虑使用以下实现:

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
现在
A[m]
A[m]。当
T
等于
A[m]
A[m]
小于
T
时,与(T)<0
相比,将
为真

因此,在这种情况下:

1 2 3 4 // array and A[m] is 2
2 // target T
2.compareTo(2)
返回
-1
,这使得算法转到下一次执行
L=m+1
->而不是返回正确的值

事实上,二进制搜索将陷入一个不定式循环,从
2.比较到(2)
3.比较到(2)
。我希望这能有所帮助。

在排序时,-10对排序列表的排序有着非常相似的影响,因为
比较
计算为0的项目将被分组在一起

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

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

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;
  }
}
在这里,我们已经覆盖了book的
compare to
,以创建一个自定义比较,该比较首先检查图书的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;
        }
    }
  }
}
公共类库{
公共静态void main(字符串[]args){
列表库=新的ArrayList();
增加(新书(“9780593098240”,“沙丘之子”);
增加(新书(“9780593098233”,“沙丘弥赛亚”);
增加(新书(“9780441172719”,“沙丘”);
//仅显示基于多个属性的排序。
收藏.分类(图书馆);
System.out.println(“图书馆中的图书:+Arrays.toString(library.toArray()));
//很明显,这里有一些用于输入书籍的代码,但是只为示例创建对象更容易。
Book newBook=新书(“9780593098240”,“沙丘之子”);
用于(图书图书馆:图书馆){
if(bookInLibrary.compareTo(newBook)==0){
System.out.println(“我们图书馆里已经有那本书了。”);
打破
}
}
}
}

这主要用于排序,因此,
compare(…)
返回的结果是等级比较,0表示等级相等。例如,
TreeSet
TreeMap
使用此方法(以及其他方法)创建元素/键的适当排序。这与方法
equals(…)
不可比较。如果您想对值的组合进行排序,比如姓氏和名字,那么您需要知道Instance的一个值何时等于对另一个值进行排序,因为有三种可能的结果。一个对象与另一个对象是“更小或更小”、“更大或更大”或“相等/相同”。这里是否有打字错误?“如果在比较的两个值相等时返回-1,则compare(f1,f2)和compare(f2,f1)都将返回-1”为什么compare(f1,f2)和compare(f2,f1)在值不同时返回-1?你的意思是比较(f1,f1)?@DerekNoble你在问为什么当f1和f2的值相等时必须返回0。因此,我解释说,如果不返回0(例如,您将返回-1),则
compare(f1,f2)
compare(f2,f1)
都将返回-1,只有某些稳定的排序算法将处理负值,而
0
则处理相同的值。它可能与其他算法的处理方式不同。除此之外,您复制了OP的错误,以假设比较器必须返回
-1
0
+1
中的一个。比较器可以返回任何int值,如果非零,则只有符号起作用。
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;
        }
    }
  }
}