ArrayList'i Tersine Çevirmenin En Kolay Yolu Nedir?


333

Bu ArrayList'i tersine çevirmenin en basit yolu nedir?

ArrayList<Integer> aList = new ArrayList<>();

//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");

while (aList.listIterator().hasPrevious())
  Log.d("reverse", "" + aList.listIterator().previous());

Yanıtlar:


798
Collections.reverse(aList);

Örnek ( Referans ):

ArrayList aList = new ArrayList();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
Collections.reverse(aList);
System.out.println("After Reverse Order, ArrayList Contains : " + aList);

2
@AgarwalShankar gerekli bir hata alıyorum ArrayList geçersiz buldu. Bir şey mi eksik?
Sagar Devanga

9
@SagarDevanga Liste ters çevrilir, iade edilmez.
Carcigenicate

Collections.reverse (Liste); Bir Android projesinde kullandım, iyi çalışıyor.
Damir Varevac

22

En basit yol değil, ancak bir özyineleme hayranıysanız, bir ArrayList'i tersine çevirmek için aşağıdaki yöntemle ilgilenebilirsiniz:

public ArrayList<Object> reverse(ArrayList<Object> list) {
    if(list.size() > 1) {                   
        Object value = list.remove(0);
        reverse(list);
        list.add(value);
    }
    return list;
}

Veya özyinelemesiz:

public ArrayList<Object> reverse(ArrayList<Object> list) {
    for(int i = 0, j = list.size() - 1; i < j; i++) {
        list.add(i, list.remove(j));
    }
    return list;
}

Yanılıyor olabilirim ama özyinelemeli olmayan örneğinizde, int jher yinelemeyle güncellenmiyor mu? Başlatırsınız j = list.size() - 1ama her yineleme ile güncellenen başlatma bölümünün öyle olduğunu düşünmüyorum for loop?
Tony Chan

@Turbo j'nin her yinelemeyle güncellenmesi gerekmez. ArrayList öğesinin son dizinine başlatılır ve son öğeye erişmek için kullanılır. For döngüsü içinde son eleman çıkarılır ve indeks i'ye eklenir; i, ArrayList öğesindeki son sıraya ulaşana kadar artırılır.
todd

1
Evet, ancak ikinci yinelemede, (orijinal ArrayList öğesinin son dizini) IndexOutOfBoundsExceptionerişmeye çalıştığınız için bir süre alamayacak mısınız, jancak nesneyi zaten bu dizindeki kaldırdınız mı?
Tony Chan

1
Üzgünüm, sadece kodu çalıştırdı, kesinlikle çalışıyor. add()Dizi esas olarak sabit bir boyut kalır böylece dizi diğer öğeleri iter unuttum . İlginç çözümler, teşekkürler!
Tony Chan

Ayrıca, sadece merak ediyorum ama özyinelemeli yöntemi nasıl buldunuz? Bunun normalde düşünebileceğim bir şey olduğunu sanmıyorum.
Tony Chan

13

Buradaki hile "geri" yi tanımlamaktadır. Listeyi yerinde değiştirebilir, ters sırada bir kopya oluşturabilir veya ters sırada bir görünüm oluşturabilirsiniz.

Basit yolu, sezgisel konuşma vardır Collections.reverse:

Collections.reverse(myList);

Bu yöntem , listeyi yerinde değiştirir . Yani, Collections.reverselisteyi alır ve öğelerinin üzerine yazar ve geri döndürülmemiş bir kopya bırakmaz. Bu, bazı kullanım durumları için uygundur, ancak diğerleri için uygun değildir; ayrıca listenin değiştirilebilir olduğunu varsayar. Eğer bu kabul edilebilirse, iyiyiz.


Değilse, ters sırayla bir kopya oluşturulabilir :

static <T> List<T> reverse(final List<T> list) {
    final List<T> result = new ArrayList<>(list);
    Collections.reverse(result);
    return result;
}

Bu yaklaşım işe yarar, ancak listenin iki kez yinelenmesini gerektirir. Copy yapıcısı ( new ArrayList<>(list)) liste üzerinde yinelenir ve öyle yapar Collections.reverse. Çok eğimliysek, bu yöntemi yalnızca bir kez yinelemek için yeniden yazabiliriz:

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

Bu daha verimlidir, ancak daha ayrıntılıdır.

Alternatif olarak, bazı kişilerin yukarıdakilerden daha özlü ve okunaklı bulduğu Java 8'in streamAPI'sını kullanmak için yukarıdakileri yeniden yazabiliriz :

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
}

nb. O Collectors.toList()sonuç listesi hakkında çok az garanti vermez. Sonucun ArrayList olarak geri gelmesini sağlamak istiyorsanız Collectors.toCollection(ArrayList::new)bunun yerine kullanın.


Üçüncü seçenek, görünümü ters sırayla oluşturmaktır . Bu daha karmaşık bir çözümdür ve daha fazla okumaya / kendi sorusuna değer. Guava'nın Listeleri # ters yöntemi geçerli bir başlangıç ​​noktasıdır.

"En basit" bir uygulamayı seçmek okuyucu için bir alıştırma olarak bırakılmıştır.


6

Ek ArrayList veya add () ve remove () yöntemlerinin birleşimini kullanmadan çözüm. Büyük bir listeyi geri çevirmeniz gerekirse her ikisinin de olumsuz etkisi olabilir.

 public ArrayList<Object> reverse(ArrayList<Object> list) {

   for (int i = 0; i < list.size() / 2; i++) {
     Object temp = list.get(i);
     list.set(i, list.get(list.size() - i - 1));
     list.set(list.size() - i - 1, temp);
   }

   return list;
 }

5
ArrayList<Integer> myArray = new ArrayList<Integer>();

myArray.add(1);
myArray.add(2);
myArray.add(3);

int reverseArrayCounter = myArray.size() - 1;

for (int i = reverseArrayCounter; i >= 0; i--) {
    System.out.println(myArray.get(i));
}

2

ArrayList'i tekrarlayan bir şekilde ve öğe eklemek için yeni bir liste oluşturmadan tersine çevirme:

   public class ListUtil {

    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("1");
        arrayList.add("2");
        arrayList.add("3");
        arrayList.add("4");
        arrayList.add("5");
        System.out.println("Reverse Order: " + reverse(arrayList));

    }

    public static <T> List<T> reverse(List<T> arrayList) {
        return reverse(arrayList,0,arrayList.size()-1);
    }
    public static <T> List<T> reverse(List<T> arrayList,int startIndex,int lastIndex) {

        if(startIndex<lastIndex) {
            T t=arrayList.get(lastIndex);
            arrayList.set(lastIndex,arrayList.get(startIndex));
            arrayList.set(startIndex,t);
            startIndex++;
            lastIndex--;
            reverse(arrayList,startIndex,lastIndex);
        }
        return arrayList;
    }

}

1

Sadece kullandığımız durumda Java 8 , o zaman Çayı'nın yararlanabilirler. ArrayList rastgele erişim listesidir ve bir öğe akışını ters sırayla alabilir ve ardından yeni bir şekilde toplayabiliriz ArrayList.

public static void main(String[] args) {
        ArrayList<String> someDummyList = getDummyList();
        System.out.println(someDummyList);
        int size = someDummyList.size() - 1;
        ArrayList<String> someDummyListRev = IntStream.rangeClosed(0,size).mapToObj(i->someDummyList.get(size-i)).collect(Collectors.toCollection(ArrayList::new));
        System.out.println(someDummyListRev);
    }

    private static ArrayList<String> getDummyList() {
        ArrayList dummyList = new ArrayList();
        //Add elements to ArrayList object
        dummyList.add("A");
        dummyList.add("B");
        dummyList.add("C");
        dummyList.add("D");
        return dummyList;
    }

Yukarıdaki yaklaşım, rastgele erişim olmadığı için LinkedList için uygun değildir. Ayrıca instanceofkontrol etmek için de kullanabiliriz.


1

Java 8'i kullanarak da aynısını yapabiliriz.

public static<T> List<T> reverseList(List<T> list) {
        List<T> reverse = new ArrayList<>(list.size());

        list.stream()
                .collect(Collectors.toCollection(LinkedList::new))
                .descendingIterator()
                .forEachRemaining(reverse::add);

        return reverse;
    }

0

Biraz daha okunabilir :)

public static <T> ArrayList<T> reverse(ArrayList<T> list) {
    int length = list.size();
    ArrayList<T> result = new ArrayList<T>(length);

    for (int i = length - 1; i >= 0; i--) {
        result.add(list.get(i));
    }

    return result;
}

0

Başka bir özyinelemeli çözüm

 public static String reverse(ArrayList<Float> list) {
   if (list.size() == 1) {
       return " " +list.get(0);
   }
   else {
       return " "+ list.remove(list.size() - 1) + reverse(list);
   } 
 }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.