Как изменить список на Java?
Я хочу иметь обратный список в списке (аналогично тому, как List#sublist
предоставляет список подписок в списке). Есть ли какая-то функция, которая предоставляет эту функциональность?
Я не хочу делать какие-либо копии списка или изменять список.
Было бы достаточно, если бы я мог получить хотя бы обратный итератор в списке в этом случае.
Кроме того, я знаю, как реализовать это сам. Я просто спрашиваю, действительно ли Java предоставляет что-то вроде этого.
Демонстрационная реализация:
static <T> Iterable<T> iterableReverseList(final List<T> l) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return new Iterator<T>() {
ListIterator<T> listIter = l.listIterator(l.size());
public boolean hasNext() { return listIter.hasPrevious(); }
public T next() { return listIter.previous(); }
public void remove() { listIter.remove(); }
};
}
};
}
Я только что узнал, что в некоторых реализациях List
есть descendingIterator()
, что мне и нужно. Хотя для List
нет такой общей реализации. Что странно, потому что реализация, которую я видел в LinkedList
, является достаточно общей для работы с любым List
.
Ответы
Ответ 1
Guava предоставляет следующее: Lists.reverse(List)
List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters);
System.out.println(reverseView); // [c, b, a]
В отличие от Collections.reverse
, это чисто представление... оно не изменяет порядок элементов в исходном списке. Кроме того, с измененным исходным списком изменения как исходного списка, так и вида отражаются в другом.
Ответ 2
Используйте метод .clone() в своем списке. Он вернет мелкую копию, что означает, что она будет содержать указатели на одни и те же объекты, поэтому вам не придется копировать список. Затем просто используйте Коллекции.
Эрго,
Collections.reverse(list.clone());
Если вы используете List
и не имеете доступа к clone()
, вы можете использовать subList()
:
List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);
Ответ 3
Если я понял правильно, это одна строка кода. Он работал у меня.
Collections.reverse(yourList);
Ответ 4
Не совсем элегантный, но если вы используете List.listIterator(int index), вы можете получить двунаправленный ListIterator в конце списка:
//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());
while (li.hasPrevious()) {
String curr = li.previous()
}
Ответ 5
Collections.reverse(nums)... Фактически он отменяет порядок элементов.
Ниже код должен быть высоко оценен -
List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
Collections.sort(nums);
Collections.reverse(nums);
System.out.println(nums);
Ответ 6
java.util.Deque
имеет descendingIterator()
- если ваш List
является Deque
, вы можете использовать его.
Ответ 7
Я знаю, что это старый пост, но сегодня я искал что-то вроде этого. В конце я сам написал код:
private List reverseList(List myList) {
List invertedList = new ArrayList();
for (int i = myList.size() - 1; i >= 0; i--) {
invertedList.add(myList.get(i));
}
return invertedList;
}
Не рекомендуется для длинных списков, это не оптимизировано вообще. Это простое решение для контролируемых сценариев (в списках, которые я обрабатываю, содержится не более 100 элементов).
Надеюсь, это поможет кому-то.
Ответ 8
Я использую это:
public class ReversedView<E> extends AbstractList<E>{
public static <E> List<E> of(List<E> list) {
return new ReversedView<>(list);
}
private final List<E> backingList;
private ReversedView(List<E> backingList){
this.backingList = backingList;
}
@Override
public E get(int i) {
return backingList.get(backingList.size()-i-1);
}
@Override
public int size() {
return backingList.size();
}
}
вот так:
ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list
Ответ 9
Вы также можете сделать это:
static ArrayList<String> reverseReturn(ArrayList<String> alist)
{
if(alist==null || alist.isEmpty())
{
return null;
}
ArrayList<String> rlist = new ArrayList<>(alist);
Collections.reverse(rlist);
return rlist;
}
Ответ 10
Вы также можете инвертировать позицию, когда вы запрашиваете объект:
Object obj = list.get(list.size() - 1 - position);
Ответ 11
Для небольшого размера мы можем создать LinkedList
, а затем использовать нисходящий итератор как:
List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
.descendingIterator().
forEachRemaining(System.out::println); // Four, Three, Two, One
System.out.println(stringList); // One, Two, Three, Four