📜 ⬆️ ⬇️

Never make subtraction comparators

I noticed that people, when they write their comparator, very often like comparison of numbers to prefer their subtraction. This approach is concise and concise, but unfortunately, it does not always work correctly, so you cannot use it. I myself once came across this, and I see it so often that I decided to write a note.

Consider the following code:

import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.util.Collections; import java.util.List; import static java.util.Arrays.*; import static org.testng.Assert.assertEquals; public class ComparatorAlgTest { List<Integer> list1, list2; @BeforeMethod public void init(){ list1 = asList(1,2); list2 = asList(Integer.MIN_VALUE, Integer.MAX_VALUE); } void check(String name){ System.out.println(name+" list1 = " + list1); System.out.println(name+" list2 = " + list2); assertEquals(list1, asList(1,2) ); assertEquals(list2, asList(Integer.MIN_VALUE, Integer.MAX_VALUE) ); } @Test public void testWrong() { Collections.sort(list1, (Integer a, Integer b) -> ab ); Collections.sort(list2, (Integer a, Integer b) -> ab ); check("wrong"); } @Test public void testFine() { Collections.sort(list1, (Integer a, Integer b) -> a.equals(b)? 0: a>b ? 1:-1 ); Collections.sort(list2, (Integer a, Integer b) -> a.equals(b)? 0: a>b ? 1:-1 ); check("fine"); } } 


By running this, you can see that testWrong () fails, and instead of sorting in ascending order, we sometimes get descending
')
fine list1 = [1, 2]
fine list2 = [-2147483648, 2147483647]
wrong list1 = [1, 2]
wrong list2 = [2147483647, -2147483648]


In fact, a pair of numbers (Integer.MIN_VALUE, Integer.MAX_VALUE) is far from the only combination in which a subtraction-driven comparator will work incorrectly. In order for the result to be incorrect, it is necessary and sufficient that an overflow occurs during subtraction. For example, you can substitute asList (-2, Integer.MAX_VALUE), and the subtraction-driven comparison does not work either.

Source: https://habr.com/ru/post/278329/


All Articles