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
@覆盖
公共整数比较(测试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)
。我希望这能有所帮助。在排序时,-1和0对排序列表的排序有着非常相似的影响,因为比较
计算为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;
}
}
}
}