Hoe krijg ik een omgekeerde lijstweergave op een lijst in Java?

Ik wil een omgekeerde lijstweergave op een lijst hebben (op een vergelijkbare manier als List#sublisteen sublijstweergave op een lijst geeft). Is er een functie die deze functionaliteit biedt?

Ik wil geen enkele kopie van de lijst maken of de lijst wijzigen.

In dit geval zou het echter voldoende zijn als ik op zijn minst een omgekeerde iterator op een lijst zou kunnen krijgen.


Ook weet ik hoe ik dit zelf moet implementeren. Ik vraag alleen of Java al zoiets biedt.

Demo-implementatie:

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(); }                 
            };
        }
    };
}

Ik ben er net achter gekomen dat sommige Listimplementaties descendingIterator()hebben, wat ik nodig heb. Hoewel er geen algemene implementatie is voor List. Dat is nogal vreemd omdat de implementatie die ik heb gezien in LinkedListalgemeen genoeg is om met elke Listte werken.


Antwoord 1, autoriteit 100%

Gebruik de .clone()-methode op uw lijst. Het zal een ondiepe kopie teruggeven, wat inhoudt dat het verwijzingen naar dezelfde objecten zal bevatten, zodat u de lijst niet hoeft te kopiëren. Gebruik dan gewoon Collecties.

Ergo,

Collections.reverse(list.clone());

Als je een Listgebruikt en geen toegang hebt tot clone(), kun je subList():

List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);

Antwoord 2, autoriteit 98%

Guavabiedt dit: Lists.reverse(List)

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

In tegenstelling tot Collections.reverse, is dit puur een weergave… het verandert niets aan de volgorde van elementen in de originele lijst. Bovendien, met een originele lijst die kan worden gewijzigd, worden wijzigingen in zowel de originele lijst als de weergave weerspiegeld in de andere.


Antwoord 3, autoriteit 35%

Als ik het goed heb begrepen, is het één regel code. Het werkte voor mij.

Collections.reverse(yourList);

Antwoord 4, autoriteit 17%

Het is niet bepaald elegant, maar als je List.listIterator(int index) gebruikt, kun je een bidirectionele ListIterator aan het einde van de lijst krijgen:

//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());
while (li.hasPrevious()) {
   String curr = li.previous()
}

Antwoord 5, autoriteit 4%

Collections.reverse(nums) … Het draait eigenlijk de volgorde van de elementen om.
Onderstaande code wordt zeer op prijs gesteld –

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);

Uitvoer: 15,94,83,42,61


Antwoord 6, autoriteit 4%

Ik gebruik dit:

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();
    }
}

zoals dit:

ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list

Antwoord 7, autoriteit 3%

java.util.Dequeheeft descendingIterator()– als uw Listeen Dequeis, kunt u gebruik dat.


Antwoord 8, autoriteit 2%

Ik weet dat dit een oud bericht is, maar vandaag was ik op zoek naar zoiets. Uiteindelijk heb ik de code zelf geschreven:

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;
}

Niet aanbevolen voor lange lijsten, dit is helemaal niet geoptimaliseerd. Het is een soort gemakkelijke oplossing voor gecontroleerde scenario’s (de lijsten die ik behandel hebben niet meer dan 100 elementen).

Ik hoop dat het iemand helpt.


Antwoord 9

U kunt de positie ook omkeren wanneer u een object aanvraagt:

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

Antwoord 10

Voor een kleine lijst kunnen we LinkedListmaken en vervolgens een aflopende iterator gebruiken als:

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

Antwoord 11

U kunt ook dit doen:

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;
}

Other episodes