Хитрость здесь в том, чтобы определить «реверс». Можно изменить список на месте, создать копию в обратном порядке или создать представление в обратном порядке.
Самый простой способ, интуитивно говоря , это Collections.reverse
:
Collections.reverse(myList);
Этот метод изменяет список на месте . То есть Collections.reverse
берет список и перезаписывает его элементы, не оставляя необратимой копии. Это подходит для некоторых случаев использования, но не для других; более того, предполагается, что список можно изменить. Если это приемлемо, у нас все хорошо.
Если нет, можно создать копию в обратном порядке :
static <T> List<T> reverse(final List<T> list) {
final List<T> result = new ArrayList<>(list);
Collections.reverse(result);
return result;
}
Этот подход работает, но требует итерации по списку дважды. Конструктор копирования ( new ArrayList<>(list)
) выполняет итерации по списку Collections.reverse
. Мы можем переписать этот метод, чтобы повторить только один раз, если мы так склонны:
static <T> List<T> reverse(final List<T> list) {
final int size = list.size();
final int last = size - 1;
// create a new list, with exactly enough initial capacity to hold the (reversed) list
final List<T> result = new ArrayList<>(size);
// iterate through the list in reverse order and append to the result
for (int i = last; i >= 0; --i) {
final T element = list.get(i);
result.add(element);
}
// result now holds a reversed copy of the original list
return result;
}
Это более эффективно, но и более многословно.
В качестве альтернативы, мы можем переписать вышеупомянутое, чтобы использовать stream
API Java 8 , который некоторые люди находят более кратким и разборчивым, чем выше:
static <T> List<T> reverse(final List<T> list) {
final int last = list.size() - 1;
return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list
.map(i -> (last - i)) // reverse order
.mapToObj(list::get) // map each index to a list element
.collect(Collectors.toList()); // wrap them up in a list
}
в северном направлении это Collectors.toList()
дает очень мало гарантий относительно списка результатов. Если вы хотите, чтобы результат вернулся в виде ArrayList, используйте Collectors.toCollection(ArrayList::new)
вместо этого.
Третий вариант - создать представление в обратном порядке . Это более сложное решение и заслуживает дальнейшего чтения / своего вопроса. Метод обратного отображения списков в Guava - жизнеспособная отправная точка.
Выбор «простейшей» реализации оставлен читателю в качестве упражнения.