Как получить перевернутый вид списка в списке на Java? - PullRequest
206 голосов
/ 18 октября 2010

Я хочу иметь перевернутое представление списка в списке (аналогично, чем 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.

Ответы [ 12 ]

203 голосов
/ 19 октября 2010

Используйте метод .clone () в своем списке. Он вернет мелкую копию, то есть он будет содержать указатели на те же объекты, поэтому вам не придется копировать список. Тогда просто используйте Коллекции.

Ergo,

Collections.reverse(list.clone());

Если вы используете List и не имеете доступа к clone(), вы можете использовать subList():

List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);
197 голосов
/ 18 октября 2010

Гуава обеспечивает это: Lists.reverse (Список)

List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters); 
System.out.println(reverseView); // [c, b, a]

В отличие от Collections.reverse, это чисто представление ... оно не изменяет порядок элементов в исходном списке. Кроме того, с исходным списком, который можно изменить, изменения как исходного списка, так и представления отражаются в другом.

80 голосов
/ 06 января 2014

Если я правильно понял, то это одна строка кода. Это сработало для меня.

 Collections.reverse(yourList);
31 голосов
/ 18 октября 2010

Это не совсем элегантно, но если вы используете List.listIterator (int index), вы можете получить двунаправленный ListIterator до конца списка:

//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());

while (li.hasPrevious()) {
   String curr = li.previous()
}
14 голосов
/ 06 августа 2016

Collections.reverse (nums) ... На самом деле это обратный порядок элементов. Ниже код должен быть высоко оценен - ​​

List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
//Tosort the collections uncomment the below line
//Collections.sort(nums); 

Collections.reverse(nums);

System.out.println(nums);

Выход: 15,94,83,42,61

4 голосов
/ 13 октября 2015

Я использую это:

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
4 голосов
/ 27 апреля 2012

Я знаю, что это старый пост, но сегодня я искал что-то подобное.В конце концов я сам написал код:

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 элементов).

Надеюсь, это кому-нибудь поможет.

4 голосов
/ 18 октября 2010

java.util.Deque имеет descendingIterator() - если ваш List является Deque, вы можете использовать это.

1 голос
/ 15 октября 2017

Для небольшого размера списка мы можем создать LinkedList и затем использовать нисходящий итератор как:

List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
         .descendingIterator().
         forEachRemaining(System.out::println); // Three, Two, One
System.out.println(stringList); // One, Two, Three
1 голос
/ 23 сентября 2016

Вы также можете инвертировать позицию при запросе объекта:

Object obj = list.get(list.size() - 1 - position);
...