#java #sorting #collections #iterator
Вопрос:
Возможно ли повторно просмотреть объекты списка ссылок без его сортировки?
class MyClasslt;Tgt; implements Iterablelt;Tgt; { private LinkedListlt;Tgt; myList = new LinkedListlt;gt;(); @Override public Iteratorlt;Tgt; iterator() { return new Iteratorlt;Tgt;() { @Override public boolean hasNext() { return false; } @Override public T next() { // SHOULD RETURN THE ELEMENTS OF MYLIST IN A SORTED WAY return null; } }; } }
В этом случае мы можем предположить, что объекты типа T имеют целое поле для сортировки
Комментарии:
1. Если
hasNext
возвращаетfalse
, тоnext
не следует вызывать вообще.
Ответ №1:
Это невозможно, если вы не создадите дополнительные методы для сортировки «на лету» или хранения предварительно заказанного списка в другом объекте (я предполагаю, что вы не хотите изменять исходный порядок списка).
Оба метода имеют свои издержки:
- Вы можете сохранить индекс «текущего» индекса и найти следующий индекс, просматривая весь список, но это стоит процессора
- Вы можете создать личную копию списка, отсортировать ее и вернуть этот новый список, но это требует больше памяти, и вам придется обновлять новый список на случай, если в исходном списке изменились значения.
Ответ №2:
Короткий ответ: Нет.
Сортировка-это своего рода поиск текущего минимума/максимума, вы никак не можете найти это, не пройдя через каждый элемент в списке, и, следовательно, вам нужно будет все это как-то отсортировать, способ сделать это-через a Heap
, что означает дополнительную память, если вы не хотите сортировать сам список.
@Override public Iteratorlt;Tgt; iterator() { PriorityQueuelt;Tgt; heap = new PriorityQueuelt;gt;(list); return new Iteratorlt;Tgt;() { @Override public boolean hasNext() { return !heap.isEmpty(); } @Override public T next() { return heap.poll(); } }; }
Комментарии:
1. Если тип «T» не реализуется
Comparable
, необходимо указатьComparator
в конструктореPriorityQueue
.
Ответ №3:
Если тип T
реализует Comparablelt;Tgt;
, вы можете сделать вот так.
static class MyClasslt;T extends Comparablelt;Tgt;gt; implements Iterablelt;Tgt; { private LinkedListlt;Tgt; myList = new LinkedListlt;gt;(); @Override public Iteratorlt;Tgt; iterator() { return myList.stream().sorted().iterator(); } } public static void main(String[] args) { MyClasslt;Integergt; obj = new MyClasslt;gt;(); obj.myList.add(2); obj.myList.add(0); obj.myList.add(1); for (int i : obj) System.out.println(i); System.out.println(obj.myList); }
выход:
0 1 2 [2, 0, 1]
В качестве альтернативы вы можете передать компаратор через конструктор.
static class MyClasslt;Tgt; implements Iterablelt;Tgt; { private LinkedListlt;Tgt; myList = new LinkedListlt;gt;(); private final Comparatorlt;Tgt; comparator; public MyClass(Comparatorlt;Tgt; comparator) { this.comparator = comparator; } @Override public Iteratorlt;Tgt; iterator() { return myList.stream().sorted(comparator).iterator(); } }