Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.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比较器接口_Java_Java 8_Comparator_Ocpjp - Fatal编程技术网

Java比较器接口

Java比较器接口,java,java-8,comparator,ocpjp,Java,Java 8,Comparator,Ocpjp,我对比较器接口及其比较方法有误解 这是下面的代码,我想知道为什么比较方法return-33我认为它应该返回33 import java.util.*; public class Sorted implements Comparable<Sorted>, Comparator<Sorted> { private int num; private String text; Sorted(int n, String t) { this.num = n; thi

我对比较器接口及其比较方法有误解 这是下面的代码,我想知道为什么比较方法return-33我认为它应该返回33

import java.util.*;
public class Sorted implements Comparable<Sorted>, Comparator<Sorted> {
private int num;
private String text;

Sorted(int n, String t) {
    this.num = n;
    this.text = t;
}

public String toString() {
    return "" + num;
}

public int compareTo(Sorted s) {
    return text.compareTo(s.text);
}

public int compare(Sorted s1, Sorted s2) {
    System.out.println(s1.num-s2.num); // return -33
    return s1.num - s2.num;
}
public static void main(String[] args) {
    Sorted s1 = new Sorted(88, "a");
    Sorted s2 = new Sorted(55, "b");
    TreeSet<Sorted> t1 = new TreeSet<>();
    t1.add(s1); t1.add(s2);
    TreeSet<Sorted> t2 = new TreeSet<>(s1);
    t2.add(s1); t2.add(s2);
    System.out.println(t1 + " " + t2);
    System.out.println(s1.num-s2.num); // prints 33
} }
import java.util.*;
公共类排序实现可比较、比较{
私有整数;
私有字符串文本;
已排序(整数n,字符串t){
this.num=n;
this.text=t;
}
公共字符串toString(){
返回“”+num;
}
公共整数比较(已排序){
返回text.compareTo(s.text);
}
公共整数比较(排序s1,排序s2){
System.out.println(s1.num-s2.num);//返回-33
返回s1.num-s2.num;
}
公共静态void main(字符串[]args){
排序s1=新排序(88,“a”);
排序s2=新排序(55,“b”);
TreeSet t1=新的TreeSet();
t1.add(s1);t1.add(s2);
树集t2=新树集(s1);
t2.添加(s1);t2.添加(s2);
系统输出打印项次(t1+“”+t2);
System.out.println(s1.num-s2.num);//打印33
} }

你可能知道如果
a-b=c
那么
b-a=-c

这里发生的情况非常相似。您似乎假设
TreeSet
调用
compare
方法如下:

comparator.compare(s1, s2)
(请注意,我使用了
s1
s2
用于演示目的。它们显然不在
treeseet的范围内
s1
与您的
s1
是同一个实例,
s2
与您的s2`是同一个实例。)

但它也可以这样调用
compare

comparator.compare(s2, s1)
不能吗

如果它以第二种方式调用它,则可以预期
-33
的结果

编辑:

我查看了
TreeSet.add
的源代码,发现它调用
TreeMap.put
,将要添加的项作为键。如果您进一步查看
TreeMap.put
,您将发现:

Comparator<? super K> cpr = comparator;
if (cpr != null) {
    do {
        parent = t;
        cmp = cpr.compare(key, t.key); // <--- "key" is the key passed into this method
                                       // "t" is an element that is already in the map
        if (cmp < 0)
            t = t.left;
        else if (cmp > 0)
            t = t.right;
        else
            return t.setValue(value);
    } while (t != null);
}
事实上,根本不需要实现
Comparator
,您可以在创建
树映射时传入
Comparator.comparingit(s->s.num)

TreeSet<Sorted> t1 = new TreeSet<>(Comparator.comparingInt(s -> s.num));
treesett1=新树集(Comparator.comparingit(s->s.num));

你可能知道如果
a-b=c
那么
b-a=-c

这里发生的情况非常相似。您似乎假设
TreeSet
调用
compare
方法如下:

comparator.compare(s1, s2)
(请注意,我使用了
s1
s2
用于演示目的。它们显然不在
treeseet的范围内
s1
与您的
s1
是同一个实例,
s2
与您的s2`是同一个实例。)

但它也可以这样调用
compare

comparator.compare(s2, s1)
不能吗

如果它以第二种方式调用它,则可以预期
-33
的结果

编辑:

我查看了
TreeSet.add
的源代码,发现它调用
TreeMap.put
,将要添加的项作为键。如果您进一步查看
TreeMap.put
,您将发现:

Comparator<? super K> cpr = comparator;
if (cpr != null) {
    do {
        parent = t;
        cmp = cpr.compare(key, t.key); // <--- "key" is the key passed into this method
                                       // "t" is an element that is already in the map
        if (cmp < 0)
            t = t.left;
        else if (cmp > 0)
            t = t.right;
        else
            return t.setValue(value);
    } while (t != null);
}
事实上,根本不需要实现
Comparator
,您可以在创建
树映射时传入
Comparator.comparingit(s->s.num)

TreeSet<Sorted> t1 = new TreeSet<>(Comparator.comparingInt(s -> s.num));
treesett1=新树集(Comparator.comparingit(s->s.num));

compare(Sorted s1,Sorted s2)
中的s1和s2是局部变量定义,您不能将它们与
main()
中的定义混淆。没有定义
TreeSet
如何比较这两个元素(算法上,仅通过实现)

compare(s1, s2) //yields 33
compare(s2, s1) //yields -33

在内部使用
put
调用在多个位置进行比较,通常将放入树集中的元素作为第一个元素。因此,
put(s2)
将调用
compare(s2,s1)
。请参阅下面的代码摘录:

public V put(K key, V value) {    
        Entry<K,V> t = root;    
        if (t == null) {
            compare(key, key); // type (and possibly null) check       
            root = new Entry<>(key, value, null);  
            size = 1;
            modCount++;    
            return null;    
        }    
        int cmp;    
        Entry<K,V> parent;    
        // split comparator and comparable paths    
        Comparator<? super K> cpr = comparator;    
        if (cpr != null) {    
            do {
                parent = t;    
                cmp = cpr.compare(key, t.key);    
                if (cmp < 0)   
                    t = t.left;    
                else if (cmp > 0)    
                    t = t.right;    
                else    
                    return t.setValue(value);    
            } while (t != null);    
        }    
        else {   
            if (key == null)    
                throw new NullPointerException();    
            @SuppressWarnings("unchecked")    
                Comparable<? super K> k = (Comparable<? super K>) key;   
            do {    
                parent = t;    
                cmp = k.compareTo(t.key);    
                if (cmp < 0)
                     t = t.left; 
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);    
            } while (t != null);    
        }    
        Entry<K,V> e = new Entry<>(key, value, parent);    
        if (cmp < 0)
                parent.left = e;    
        else    
            parent.right = e;    
        fixAfterInsertion(e);    
        size++;    
        modCount++;

        return null;
    }
public V put(K键,V值){
条目t=根;
如果(t==null){
比较(key,key);//类型(可能为null)检查
root=新条目(键、值、空);
尺寸=1;
modCount++;
返回null;
}    
int-cmp;
进入父母;
//拆分比较器和可比较路径

比较器compare(Sorted s1,Sorted s2)
中的s1和s2是局部变量定义,您不能将它们与
main()
中的定义混淆。它没有定义
TreeSet
如何比较这两个元素(算法上,仅通过实现)

compare(s1, s2) //yields 33
compare(s2, s1) //yields -33

内部使用。
put
调用在多个位置进行比较,通常将放入树集中的元素作为第一个元素。因此
put(s2)
将调用
compare(s2,s1)
。请参阅下面的代码摘录:

public V put(K key, V value) {    
        Entry<K,V> t = root;    
        if (t == null) {
            compare(key, key); // type (and possibly null) check       
            root = new Entry<>(key, value, null);  
            size = 1;
            modCount++;    
            return null;    
        }    
        int cmp;    
        Entry<K,V> parent;    
        // split comparator and comparable paths    
        Comparator<? super K> cpr = comparator;    
        if (cpr != null) {    
            do {
                parent = t;    
                cmp = cpr.compare(key, t.key);    
                if (cmp < 0)   
                    t = t.left;    
                else if (cmp > 0)    
                    t = t.right;    
                else    
                    return t.setValue(value);    
            } while (t != null);    
        }    
        else {   
            if (key == null)    
                throw new NullPointerException();    
            @SuppressWarnings("unchecked")    
                Comparable<? super K> k = (Comparable<? super K>) key;   
            do {    
                parent = t;    
                cmp = k.compareTo(t.key);    
                if (cmp < 0)
                     t = t.left; 
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);    
            } while (t != null);    
        }    
        Entry<K,V> e = new Entry<>(key, value, parent);    
        if (cmp < 0)
                parent.left = e;    
        else    
            parent.right = e;    
        fixAfterInsertion(e);    
        size++;    
        modCount++;

        return null;
    }
public V put(K键,V值){
条目t=根;
如果(t==null){
比较(key,key);//类型(可能为null)检查
root=新条目(键、值、空);
尺寸=1;
modCount++;
返回null;
}    
int-cmp;
进入父母;
//拆分比较器和可比较路径

Comparator比较中的s1和s2(排序的s1,排序的s2)是局部变量定义,您不能将它们与main()中的定义混淆。TreeSet如何比较这两个元素并没有定义(算法上,仅由实现定义)。当然,我同意您的看法。但这正是我试图弄明白的(TreeSet如何比较两个元素)compare(排序的s1,排序的s2)中的s1和s2是局部变量定义,您不能将它们与main()中的定义混淆。TreeSet如何比较这两个元素并没有定义(算法上,仅由实现来定义)。当然,我同意您的看法。但这正是我试图弄明白的(TreeSet如何比较两个元素)我同意你的看法,但在其他一些程序中,它称之为正常方式,而不是v