2

I have learned how to create my own Comparator, for example, create a simple one to compare based on absolute value

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

And of course, this can be used for a customized sort:

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]

So this is all good, but what if I want to just compare two Integers based on this comparator to give a boolean value?

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

So how do I get a true by comparing -2 and 1, using absComparator?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
jxie0755
  • 1,682
  • 1
  • 16
  • 35

5 Answers5

6

Call compare directly and check the result against 0 using the same relational operator. If you want to check -2 > 1, pass those two numbers in as parameters and check if the result is > 0.

Comparator<Integer> comparator = new absComparator();
System.out.println(comparator.compare(-2, 1) > 0);
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
2

IMO, method like isGreaterThan, isLessThan should be added to Comparator interface.
Since we don't have these in this moment, we can create our own interface extending Comparator, and add default method isGreaterThan, isLessThan, as follow:

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));
    }
}

P.S.
a * a may overflow, you may refer to my example for more robust comparison.


References
The Java™ Tutorials Default Method
Java Doc Comparator
How does Java handle integer underflows and overflows and how would you check for it?

samabcde
  • 6,988
  • 2
  • 25
  • 41
1

Java does not support operator overloading.

That being said, you can easily define your own static method for it:

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

And then import it statically and use it operator-like:

import static your.UtilityClass.gteAbs;

[...]

int a = 5;
int b = -6;

if (gtAbs(a,b)) {
    // do work
}
samabcde
  • 6,988
  • 2
  • 25
  • 41
Polygnome
  • 7,639
  • 2
  • 37
  • 57
  • @GiorgiTsiklauri Well. if you compare an int using `> 0` you get a boolean. I think thats pretty self-explanatory. – Polygnome Oct 23 '20 at 14:11
1

First, your problem is that you are not using your comparator.

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);
}

But your comparator has a more fundamental problem. The following also
prints true. This is due to integer overflow when you subtract the products.

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

To correct the problem, write your comparator as follows:

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;
    }
}



WJS
  • 36,363
  • 4
  • 24
  • 39
0

Use an instance of your comparator:

absComparator comp = new absComparator();

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

if (result > 0) {
    // -2 > 1 (according to your comparator)
}
fps
  • 33,623
  • 8
  • 55
  • 110