Java'da Bir Listeyi Tersine Çevirme – Yerinde ve Yer Dışı

Bu kısa öğreticide, Java'da yerinde ve yerinde olmayan bir listeyi nasıl tersine çevireceğinizi öğreneceksiniz.

Yerinde ve Yerinde Olmadan Tersine Çevirme

Listelerde işlemler gerçekleştirirken, işlemlerin yerinde mi yapıldığını (değişiklikler orijinal nesnede uygulanır) veya yerinde mi (değişiklikler bir kopyada ve orijinal nesnede uygulanır) dikkate almak isteyebilirsiniz. nesne değişmez).

Bazı diller ve kitaplıklar farklı varsayılan davranışları tercih eder. Java'da, tersine çevirme listelerindeki çoğu işlem Yerinde.

İstediğiniz davranış buysa - harika! Değilse, kopyayı tersine çevirmeden önce listenin bir kopyasını oluşturmak isteyeceksiniz:

List list = new ArrayList(Arrays.asList(1, 2, 3));
List listCopy = new ArrayList(list);

Not: The clone() yöntem değil derin bir kopya oluşturun. kullanarak bir liste oluşturma new ArrayList(list) değil derin bir kopya oluşturun. Derin kopyalar oluşturmak önerilmez ve genel bir şekilde yapmak şaşırtıcı derecede zordur (ve listedeki veri türlerine bağlı olarak bazı durumlarda mantıklı değildir). Bu, geri dönmenizi engellemez list ve değil unsurlarına sahip olmak listCopy tersine çevriliyor ama.

Koleksiyonlar.ters()

The Collections.reverse() yöntem, bir koleksiyonu tersine çevirmek için standart yöntemdir ve "eksik" olarak işlev görür. List.reverse() yöntem. Listeyi yerinde tersine çevirir:

List list = new ArrayList(Arrays.asList(1, 2, 3));
List listCopy = new ArrayList(list);

Collections.reverse(list);

System.out.println(list);     
System.out.println(listCopy); 

Guava'nın Listeleri.reverse(liste)

Halihazırda projenizde Google Guava kullanıyorsanız, Lists sunan sınıf, reverse() orijinal listeyi yerinde sıralamayan, ancak bir kopya oluşturan ve kopyayı tersine çeviren yöntem:

List list = new ArrayList(Arrays.asList(1, 2, 3));
List reversedList = Lists.reverse(list);

System.out.println(list);         
System.out.println(reversedList); 

Henüz sahip değilseniz, Google Guava'yı Maven kullanarak projenize bağımlılığını dahil ederek projenize ekleyebilirsiniz. pom.xml Dosya:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
</dependency>

Veya Gradle aracılığıyla:

implementation group: 'com.google.guava', name: 'guava'

Not: Halihazırda Google Guava'nız yoksa veya onu projenizin diğer bölümleri için kullanmayı düşünmüyorsanız, onu yalnızca bu işlem için içe aktarmayın ve Google Guava'ya bağlı kalın. Collections.reverse() yöntem. Guava büyük bir bağımlılıktır ve onu yalnızca bu operasyon için kullanmak büyük bir aşırılıktır.

List.add() ve List.remove()

Listeyi tersine çevirmenin yanı sıra ek işlemler yapmak isterseniz - orijinal listeyi yineleyebilir, sondan öğeleri kaldırabilir, rastgele bir yöntemden geçirebilir ve listenin başına geri ekleyebilirsiniz:


public static int process(int input) {
    return input;
}

List list = new ArrayList(Arrays.asList(1, 2, 3));

for (int i = 0, j = list.size()-1; i <= j; i++) {
    int lastValue = process(list.remove(j));
    list.add(i, lastValue);
}

System.out.println(list);  

kıyaslama

Peki en hızlısı hangisi? Bu aynı zamanda işlemi yerinde mi yoksa yerinde mi yapmak istediğinize de bağlıdır.

Yerinde Geri Çevirme Kıyaslaması

Yerinde olmayandan başlayarak her üç yöntemin her iki yaklaşımını da karşılaştıralım:

List list = new Random().ints(100, 1, 11)
                .boxed()
                .collect(Collectors.toList());

int runs = 1000;

long start1 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    reverseListCollections(list);
}
long end1 = System.currentTimeMillis();
System.out.println(String.format("Collections.reverse() took: %s miliseconds", end1-start1));

long start2 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    reverseListGuava(list);
}
long end2 = System.currentTimeMillis();
System.out.println(String.format("Guava's Lists.reverse() took: %s miliseconds", end2-start2));

long start3 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    reverseListManually(list);
}
long end3 = System.currentTimeMillis();
System.out.println(String.format("Manually took: %s miliseconds", end3-start3));

System.out.println("Original list: " + list);

Bunun sonucu:

Collections.reverse() took: 3 miliseconds
Guava's Lists.reverse() took: 4 miliseconds
Manually took: 13 miliseconds
Original list: [6, 7, 9, 7, 2, 5, 4, 1, 3, 2, 2, 6, ...

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

Öğe sayısını 100'den 1000'e çıkardığımızda ne olur?

Collections.reverse() took: 9 miliseconds
Guava's Lists.reverse() took: 4 miliseconds
Manually took: 133 miliseconds
Original list: [10, 2, 2, 6, 2, 4, 7, 3, 9, 2, 7, 5, ...

Guava 4ms işaretini koruyor! Manuel yaklaşım en kötü zaman karmaşıklığına sahiptir ve doğrusal olarak artmıştır. Collections.reverse() ölçeklendirmeden daha az zarar görür, ancak Guava'nın uygulaması en az zarar görür. Yine de Guava yaklaşımı için listeyi manuel olarak kopyalamadığımızı unutmayın. "Orijinal" ve "tersine çevrilmiş" bir listeye sahip olma fikrinden vazgeçtiğimizde kıyaslama değişecek mi?

Yerinde Olmayan Tersine Çevirme Kıyaslaması

1000 öğeyle ve her biri, her yöntemden manuel kopyayı kaldırdığımızda ve kodu yeniden çalıştırdığımızda (zaman ölçümlerinin dışında bırakılan) listenin tersine çevrilmemiş bir kopyası üzerinde çalışıyor:

Collections.reverse() took: 7 miliseconds
Guava's Lists.reverse() took: 3 miliseconds
Manually took: 131 miliseconds
Original list: [6, 8, 10, 7, 3, 8, 7, 1, 1, 9, 5, ...

Guava yine de her ikisinden de sürekli olarak daha iyi performans göstermeyi başarır Collections.reverse() ve manuel yaklaşım.

Sonuç

Bu kısa kılavuzda, orijinal listeyi işlemden koruyarak Java'da yerinde ve yerinde olmayan bir listeyi nasıl tersine çevireceğinizi öğrendiniz. biz kullandık Collections.reverse() yöntem, Google Guava'nın Lists.reverse() yöntem ve manuel bir yaklaşım.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı