Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8287507

IOOBE on FilteredList based on SortedList with duplicate entries

XMLWordPrintable

    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      There is a FilteredList created based on a SortedList that is based on an ObservableList. ObservableList contains duplicate elements (compareTo() returns 0 for them). When removing almost all elements from the base ObservableList using the removeAll() method an IndexOutOfBoundsException is raised in the FilteredList.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Create an empty ObservableList
      2. Create SortedList based on ObservableList with natural ordering
      3. Create FilteredList based on SortedList
      4. Add some elements in ObseravbleList with duplicates (for example, 10+ duplicates for each element)
      5. Remove 90%+ elements from ObservableList using removeAll() method

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No exception is raised.
      ACTUAL -
      java.lang.IndexOutOfBoundsException is raised.

      ---------- BEGIN SOURCE ----------
      public class FilteredListTest {
          private static volatile boolean platformInitialized = false;


          @Test(timeout = 1000)
          public void test() throws ExecutionException, InterruptedException {
              final var UNIQUE_ITEMS_NUM = 5;
              final var REPEAT_ITEMS = 10;

              var res = new CompletableFuture<>();
              Runnable test = () -> {
                  platformInitialized = true;
                  Thread.currentThread().setUncaughtExceptionHandler((t, e) -> res.completeExceptionally(e));

                  // Lists
                  ObservableList<Integer> list = FXCollections.observableArrayList();
                  var sorted = list.sorted();
                  var filtered = new FilteredList<>(sorted);

                  // Filling the list
                  for (var i = 1; i <= UNIQUE_ITEMS_NUM; i++) {
                      for (var j = 0; j < REPEAT_ITEMS; j++) {
                          list.add(i);
                      }
                  }
                  Assert.assertEquals(UNIQUE_ITEMS_NUM * REPEAT_ITEMS, list.size());

                  // Removing items
                  var toRemove = IntStream
                          .range(1, UNIQUE_ITEMS_NUM)
                          .boxed()
                          .collect(Collectors.toList());
                  Assert.assertEquals(UNIQUE_ITEMS_NUM - 1, toRemove.size());
                  list.removeAll(toRemove);

                  res.complete(filtered.size());
              };

              if (platformInitialized) {
                  Platform.runLater(test);
              } else {
                  Platform.startup(test);
              }

              Assert.assertEquals(REPEAT_ITEMS, res.get());
          }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Remove elements one by one:

      toRemove.forEach(list::removeAll);

      instead

      list.removeAll(toRemove);

      FREQUENCY : often


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: