2

我已经学会了如何创建自己的Comparator,例如,创建一个简单的比较基于absolute value

class absComparator implements Comparator<Integer> {
    public int compare(Integer a, Integer b) {
        return a * a - b * b;
    }
}

当然,这可以用于自定义排序:

List<Integer> list_1 = new ArrayList<>(Arrays.asList(-3, -2, -1, 0, 1, 2));
list_1.sort(new absComparator());
>>> [0, -1, 1, -2, 2, -3]

所以这一切都很好,但是如果我只想根据这个比较器比较两个整数以给出一个布尔值呢?

// Currently:
System.out.println(-2>1);
>>> false

那么我如何true通过比较-2and来获得 a 1,使用absComparator

4

5 回答 5

6

直接调用并使用相同的关系运算符compare检查结果。0如果要检查-2 > 1,请将这两个数字作为参数传入并检查结果是否为> 0.

Comparator<Integer> comparator = new absComparator();
System.out.println(comparator.compare(-2, 1) > 0);
于 2020-10-23T13:49:26.447 回答
2

IMO,类似的方法isGreaterThanisLessThan应该添加到Comparator接口中。
由于我们暂时没有这些,我们可以创建自己的接口扩展Comparator,并添加默认方法 isGreaterThanisLessThan如下:

public interface EnhancedComparator<T> extends Comparator<T> {
    default boolean isGreaterThan(T target, T compareTo) {
        return this.compare(target, compareTo) > 0;
    }

    default boolean isLessThan(T target, T compareTo) {
        return this.compare(target, compareTo) < 0;
    }
}

public class AbsoluteValueComparator implements EnhancedComparator<Integer> {
    @Override
    public int compare(Integer a, Integer b) {
        a = Math.abs(a);
        b = Math.abs(b);
        return a.compareTo(b);
    }
}

public class EnhancedComparatorTest {
    public static void main(String[] args) {
        EnhancedComparator<Integer> absoluteValueComparator = new AbsoluteValueComparator();
        System.out.println("2 greater than 3 " + absoluteValueComparator.isGreaterThan(2, 3));
        System.out.println("-3 greater than -2 " + absoluteValueComparator.isGreaterThan(-3, -2));
        System.out.println("2 less than 3 " + absoluteValueComparator.isLessThan(2, 3));
        System.out.println("-3 less than -2 " + absoluteValueComparator.isLessThan(-3, -2));
    }
}

PS
a * a可能会溢出,您可以参考我的示例进行更稳健的比较。


参考
Java™ 教程 默认方法
Java Doc Comparator
Java 如何处理整数下溢和上溢以及如何检查它?

于 2020-10-23T14:56:08.320 回答
1

Java 不支持运算符重载。

话虽如此,您可以轻松地为它定义自己的静态方法:

private static final Comparator<Integer> ABS_CMP = new AbsComparator();
public static boolean gtAbs (int a, int b) {
    return ABS_CMP.compare(a, b) > 0;
}

然后静态导入它并像运算符一样使用它:

import static your.UtilityClass.gteAbs;

[...]

int a = 5;
int b = -6;

if (gtAbs(a,b)) {
    // do work
}
于 2020-10-23T13:59:18.020 回答
1

首先,您的问题是您没有使用比较器。

class absComparator implements Comparator<Integer> {
    public int compare(Integer a, Integer b) {
        return a * a - b * b;
    }
}

absComparator comp = new absComparator();

if (comp.compare(-2,1)) > 0) {
   System.out.println(true);
}

但是您的比较器有一个更根本的问题。以下也
打印为真。这是由于减去产品时的整数溢出。

if (comp.compare(12345678, 123456789) > 0) {        
    System.out.println(true);
}

要纠正这个问题,请按如下方式编写比较器:

class absComparator implements Comparator<Integer> {
    public int compare(Integer a, Integer b) {
        // eliminate the need for products by 
        // getting abs (Math.abs() also available);      
        int a1 = a >= 0 ? a : -a;
        int b1 = b >= 0 ? b : -b;
        // but you still should not subract as overflow can
        // still happen for large values of a1 and b1
        return a1 > b1 ? 1 : a1 < b1 ? -1 : 0;
        // or return Integer.compare(a1,b1);
        // or if (a1 > b1) {
        //         return 1;
        //     }
        //     if (a1 < b1) {
        //        return -1;
        //     }
        //     return 0;
    }
}



于 2020-10-23T14:54:13.533 回答
0

使用比较器的一个实例:

absComparator comp = new absComparator();

int result = comp.compare(-2, 1);

if (result > 0) {
    // -2 > 1 (according to your comparator)
}
于 2020-10-23T14:21:35.763 回答