Есть ли эффективный способ получить элементы из одного индекса в другой индекс в коллекции, не изменяя его на ArrayList? - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь реализовать разбиение на страницы в приложении загрузки java / spring в коллекции, которая возвращается из функции. Я хочу получить страницы, упорядоченные по каждому элементу startTime. Поэтому, если пользователь запрашивает страницу 2, и на каждой странице есть 10 элементов, я бы хотел предоставить пользователю элементы с 10-20 самыми последними моментами запуска. С тех пор я пробовал два подхода: а) преобразование возвращенной коллекции в массив с последующим использованием в нем IntStream для получения элементов из одного индекса в другой.

final exampleClass[] example = exampleCollection.toArray(new exampleClass[0]);
Collection<exampleClass> examplePage = IntStream.range(start, end)
    ...

б) преобразование возвращенной коллекции в ArrayList а затем с помощью Pageable / PageRequest для создания новой страницы из этого ArrayList.

Проблема в том, что они кажутся очень неэффективными, поскольку мне сначала нужно изменить Collection на ArrayList или массив, а затем работать с ним. Я хотел бы знать, есть ли более эффективные способы превратить коллекции в структуры, которые я могу повторять с помощью индексов, чтобы реализовать разбиение на страницы. Или, если есть некоторые функции Spring для создания страниц, для которых не требуются параметры, отличные от Collection. Однако я не могу найти никаких функций Spring для создания страниц, которые это делают.

Кроме того, есть ли разница во времени выполнения между

List<exampleClass> x = new ArrayList<>(exampleCollection);

и

 List<exampleClass> x = (List<exampleClass>)exampleCollection;

Ответы [ 2 ]

0 голосов
/ 09 июля 2020

Коллекция не обязательно должна иметь последовательный порядок итераций: если вы вызовете iterator() дважды, вы можете получить две разные последовательности. Преобразование коллекции в массив или список - лучшее решение.

Что касается второго вопроса: эта строка кода:

List<exampleClass> x = new ArrayList<>(exampleCollection);

создает новый список ArrayList, который является мелкая копия оригинальной коллекции. То есть он содержит указатели на те же объекты, что и исходная коллекция, но сам список является новым, и вы можете, например, отсортировать список, добавить или удалить элементы, не затрагивая исходную коллекцию. По сравнению с:

List<exampleClass> x = (List<exampleClass>)exampleCollection;

Предполагая, что exampleCollection на самом деле является списком, это дает вам указатель на этот список с новым типом данных. Если вы внесете изменения, такие как сортировка, добавление или удаление элементов, вы увидите эти изменения в exampleCollection. С другой стороны, если exampleCollection не является списком, вы получите ошибку времени выполнения (ClassCastException).

0 голосов
/ 09 июля 2020

Я хотел бы знать, есть ли более эффективные способы превратить коллекции в структуры, которые я могу повторять с помощью индексов

Единственный эффективный способ - проверить с помощью instanceof, если ваша коллекция действительно List. Если это так, то вы можете преобразовать его и просто использовать, например, sublist(start, stop) для получения результата с разбивкой на страницы.

Обратите внимание, что доступ к элементу по его индексу также может быть неэффективным. В LinkedList доступ к элементу является операцией O (N), поэтому доступ к M элементам по индексу производит операцию O (M * N), тогда как использование sublist() является операцией O (M + N).

Существует специализация интерфейса List, которая используется для отметки списков, к которым быстро осуществляется доступ по индексу, а именно: RandomAccess, вы можете или не захотите проверить это, чтобы решить лучшая стратегия.

Кроме того, есть ли разница во времени выполнения между

List x = new ArrayList <> (exampleCollection);

и

List<exampleClass> x = (List<exampleClass>)exampleCollection;

Абсолютно точно.

Второй - отливка и практически не требует затрат. Просто помните, что x и exampleCollection - это один и тот же объект (изменение одного аналогично изменению другого). Очевидно, что приведение может завершиться неудачно с ClassCastException, если exampleCollection на самом деле не является списком.

Первый выполняет копирование, которое требует затрат как в ЦП (обход exampleCollection), так и в памяти (выделение массив размеров коллекции). И то, и другое довольно мало для небольших коллекций, но ваш пробег может отличаться.

...