94 lines
2.7 KiB
Plaintext
94 lines
2.7 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Assuming that a comparator or `compareTo` method always returns -1 or 1 if the first operand is less than or greater than the second is incorrect.
|
|
|
|
The specifications for both methods, `Comparator.compare` and `Comparable.compareTo`, state that their return value is "a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object."
|
|
Even if a specific comparator always returns -1, 0, or 1, this is only an implementation detail, not the API contract developers can rely on.
|
|
|
|
== How to fix it
|
|
|
|
Replace
|
|
|
|
- `== -1` with `< 0` (the first operand is less than the second)
|
|
- `== 1` with `> 0` (the first operand is greater than the second)
|
|
- `!= -1` with `>= 0` (the first operand is greater than or equal to the second)
|
|
- `!= 1` with `\<= 0` (the first operand is less than or equal to the second)
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
public class Main {
|
|
|
|
boolean isAGreaterThanB(Comparable<Integer> a, Integer b) {
|
|
return a.compareTo(b) == 1; // Noncompliant, check for constant return value
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
ByteComparator comparator = new ByteComparator();
|
|
if (comparator.compare((byte) 23, (byte) 42) == -1) { // Noncompliant, check for constant return value
|
|
System.out.println("23 < 42");
|
|
} else {
|
|
System.out.println("23 >= 42");
|
|
}
|
|
}
|
|
|
|
static class ByteComparator implements Comparator<Byte> {
|
|
@Override
|
|
public int compare(Byte a, Byte b) {
|
|
return a - b;
|
|
}
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
public class Main {
|
|
|
|
boolean isAGreaterThanB(Comparable<Integer> a, Integer b) {
|
|
return a.compareTo(b) > 0; // Compliant, check for positive return value
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
ByteComparator comparator = new ByteComparator();
|
|
if (comparator.compare((byte) 23, (byte) 42) < 0) { // Compliant, check for negative return value
|
|
System.out.println("23 < 42");
|
|
} else {
|
|
System.out.println("23 >= 42");
|
|
}
|
|
}
|
|
|
|
static class ByteComparator implements Comparator<Byte> {
|
|
@Override
|
|
public int compare(Byte a, Byte b) {
|
|
return a - b;
|
|
}
|
|
}
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T-[Java SE 8 API Specification: Comparable.compareTo]
|
|
* https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#compare-T-T-[Java SE 8 API Specification: Comparator.compare]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Only the sign of the result should be examined.
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|