From 9c649235bbb75181959b08ed03b005264c2f11e1 Mon Sep 17 00:00:00 2001 From: Loay Ghreeb Date: Sun, 28 Jul 2024 06:35:05 +0300 Subject: [PATCH 1/2] Fix SortedList to maintain insertion order for equal elements --- .../transformation/SortedList.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/javafx.base/src/main/java/javafx/collections/transformation/SortedList.java b/modules/javafx.base/src/main/java/javafx/collections/transformation/SortedList.java index ad76c0647da..dd5ed011666 100644 --- a/modules/javafx.base/src/main/java/javafx/collections/transformation/SortedList.java +++ b/modules/javafx.base/src/main/java/javafx/collections/transformation/SortedList.java @@ -62,8 +62,6 @@ public final class SortedList extends TransformationList{ private final SortHelper helper = new SortHelper(); - private final Element tempElement = new Element<>(null, -1); - /** * Creates a new SortedList wrapped around the source list. @@ -298,7 +296,12 @@ public ElementComparator(Comparator comparator) { @Override public int compare(Element o1, Element o2) { - return comparator.compare(o1.e, o2.e); + int result = comparator.compare(o1.e, o2.e); + if (result != 0) { + return result; + } else { + return Integer.compare(o1.index, o2.index); + } } } @@ -325,24 +328,23 @@ private void updateIndices(int from, int viewFrom, int difference) { } } - private int findPosition(E e) { + private int findPosition(Element element) { if (sorted.length == 0) { return 0; } - tempElement.e = e; - int pos = Arrays.binarySearch(sorted, 0, size, tempElement, elementComparator); - return pos; + return Arrays.binarySearch(sorted, 0, size, element, elementComparator); } private void insertToMapping(E e, int idx) { - int pos = findPosition(e); + Element newElement = new Element<>(e, idx); + int pos = findPosition(newElement); if (pos < 0) { pos = ~pos; } ensureSize(size + 1); updateIndices(idx, pos, 1); System.arraycopy(sorted, pos, sorted, pos + 1, size - pos); - sorted[pos] = new Element<>(e, idx); + sorted[pos] = newElement; System.arraycopy(perm, idx, perm, idx + 1, size - idx); perm[idx] = pos; ++size; From 1df33b30d2fe502348f73f75077738104604a2eb Mon Sep 17 00:00:00 2001 From: Loay Ghreeb Date: Sun, 28 Jul 2024 06:36:42 +0300 Subject: [PATCH 2/2] Add test case --- .../javafx/collections/SortedListTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/modules/javafx.base/src/test/java/test/javafx/collections/SortedListTest.java b/modules/javafx.base/src/test/java/test/javafx/collections/SortedListTest.java index 7ea8d9cd6bd..93f45689a15 100644 --- a/modules/javafx.base/src/test/java/test/javafx/collections/SortedListTest.java +++ b/modules/javafx.base/src/test/java/test/javafx/collections/SortedListTest.java @@ -609,4 +609,26 @@ public void testGetViewIndexOutOfBounds() { assertThrows(IndexOutOfBoundsException.class, () -> sortedList.getViewIndex(sortedList.size())); assertDoesNotThrow(() -> sortedList.getViewIndex(sortedList.size() - 1)); } + + @Test + public void testSortingMaintainsInsertionOrderForEqualElements() { + ObservableList list = FXCollections.observableArrayList(); + + Person p1 = new Person("a"); + Person p2 = new Person("b"); + Person p3 = new Person("a"); + + list.addAll(p2, p1); + // After adding p2 and p1, list= [p2, p1], sorted list= [p1, p2] + SortedList sorted = new SortedList<>(list, Comparator.comparing(p -> p.name.get())); + + list.add(p3); + // After adding p3, list= [p2, p1, p3] + // p1 and p3 have equal names, but p3 was added after p1, so p3 should come after p1 in the sorted list + // Expected sorted list= [p1, p3, p2] + + assertSame(sorted.get(0), p1); + assertSame(sorted.get(1), p3); + assertSame(sorted.get(2), p2); + } }