Membalikkan Daftar di Java – Di Tempat dan Di Luar Tempat

Dalam tutorial singkat ini, Anda akan belajar bagaimana membalikkan daftar di tempat dan di luar tempat di Java.

Membalik Di Tempat dan Di Luar Tempat

Saat melakukan operasi pada daftar – Anda mungkin ingin mempertimbangkan apakah operasi dilakukan di tempat (perubahan diberlakukan pada objek asli), atau apakah tidak pada tempatnya (perubahan dilakukan pada salinan, dan objek tidak berubah).

Beberapa bahasa dan pustaka lebih menyukai perilaku default yang berbeda. Di Jawa, sebagian besar operasi pada daftar pembalik adalah di tempat.

Jika ini adalah perilaku yang Anda inginkan – bagus! Jika tidak, Anda ingin membuat salinan daftar sebelum membalik salinan:

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

Catatan: Grafik clone() metode tidak membuat salinan yang dalam. Membuat daftar menggunakan new ArrayList(list) tidak membuat salinan yang dalam. Membuat salinan yang dalam tidak disarankan, dan secara mengejutkan sulit dilakukan dengan cara umum (dan tidak masuk akal dalam beberapa kasus, tergantung pada tipe data dalam daftar). Ini tidak akan menghentikan Anda untuk bisa mundur list dan tidak memiliki unsur listCopy sedang terbalik, meskipun.

Koleksi.terbalik()

Grafik Collections.reverse() metode adalah metode standar untuk membalikkan koleksi, dan bertindak sebagai "hilang" List.reverse() metode. Ini membalikkan daftar di tempat:

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

Daftar Jambu Biji.reverse(daftar)

Jika Anda sudah menggunakan Google Guava dalam proyek Anda, Anda juga dapat memanfaatkan Lists kelas, yang menawarkan reverse() metode, yang tidak mengurutkan daftar asli di tempat, tetapi membuat salinan dan membalikkan salinan:

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

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

Jika Anda belum memilikinya, Anda dapat menambahkan Google Guava ke proyek Anda menggunakan Maven, dengan menyertakan ketergantungannya di pom.xml File:

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

Atau melalui Gradle:

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

Catatan: Jika Anda belum memiliki Google Guava, atau tidak bermaksud menggunakannya untuk bagian lain dari proyek Anda – jangan mengimpornya hanya untuk operasi ini, dan tetap berpegang pada Collections.reverse() metode. Jambu biji adalah ketergantungan yang besar, dan itu adalah berlebihan besar menggunakannya untuk operasi ini saja.

List.add() dan List.remove()

Jika Anda ingin melakukan operasi tambahan selain hanya membalikkan daftar – Anda dapat mengulangi daftar asli, menghapus elemen dari akhir, meneruskannya melalui metode arbitrer, dan menambahkannya kembali di awal daftar:


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

patokan

Jadi, mana yang tercepat? Ini juga tergantung pada apakah Anda ingin melakukan operasi di tempat atau di luar tempat.

Tolok Ukur Pembalikan di Tempat

Mari kita tolok ukur kedua pendekatan pada ketiga metode tersebut, dimulai dengan tidak pada tempatnya:

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

Ini menghasilkan:

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, ...

Lihat panduan praktis dan praktis kami untuk mempelajari Git, dengan praktik terbaik, standar yang diterima industri, dan termasuk lembar contekan. Hentikan perintah Googling Git dan sebenarnya belajar itu!

Apa yang terjadi ketika kita menambah jumlah elemen dari 100 menjadi 1000?

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, ...

Jambu biji mempertahankan tanda 4ms! Pendekatan manual memiliki kompleksitas waktu terburuk, dan meningkat secara linier. Collections.reverse() menderita lebih sedikit dari peningkatan, tetapi implementasi Guava paling tidak menderita. Meskipun demikian, perlu diingat bahwa kami tidak menyalin daftar secara manual untuk pendekatan Guava. Akankah tolok ukur berubah ketika kita membuang gagasan memiliki daftar "asli" dan "terbalik"?

Tolok Ukur Pembalikan di Luar Tempat

Dengan 1000 elemen, dan masing-masing beroperasi pada salinan daftar yang tidak dibalik (yang dikeluarkan dari pengukuran waktu), saat kami menghapus salinan manual dari setiap metode dan menjalankan kembali kode:

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, ...

Jambu biji masih berhasil secara konsisten mengungguli keduanya Collections.reverse() dan pendekatan manual.

Kesimpulan

Dalam panduan singkat ini, Anda telah mempelajari cara membalikkan daftar di Java, di tempat dan di luar tempat, mempertahankan daftar asli dari operasi. Kami telah menggunakan Collections.reverse() metode, Google Guava's Lists.reverse() metode dan pendekatan manual.

Stempel Waktu:

Lebih dari penyalahgunaan