Apa cara paling sederhana untuk menemukan jika dua Daftar berisi elemen yang persis sama, di perpustakaan Java standar?
Seharusnya tidak masalah jika kedua Daftar adalah instance yang sama atau tidak, dan seharusnya tidak masalah jika parameter tipe Daftar berbeda.
misalnya
List list1
List<String> list2;
// ... construct etc
list1.add("A");
list2.add("A");
// the function, given these two lists, should return true
Mungkin ada sesuatu yang menatapku di wajah, aku tahu :-)
EDIT: Untuk memperjelas, saya mencari EXACT elemen yang sama dan jumlah elemen, secara berurutan.
java
collections
Grundlefleck
sumber
sumber
Jawaban:
Jika Anda peduli tentang pesanan, maka gunakan metode sama dengan:
Dari javadoc:
Jika Anda ingin memeriksa independen dari pesanan, Anda bisa menyalin semua elemen ke Set dan menggunakan sama dengan Set yang dihasilkan:
Keterbatasan pendekatan ini adalah tidak hanya mengabaikan ketertiban, tetapi juga frekuensi elemen duplikat. Misalnya, jika
list1
["A", "B", "A"] danlist2
[[A], "B", "B"]Set
pendekatan akan menganggap mereka sama.Jika Anda harus tidak sensitif untuk memesan tetapi peka terhadap frekuensi duplikat Anda dapat:
sumber
a = [x, y, x]
danb = [x, y, z]
kemudian ukurannya sama danb.containsAll(a)
akan mengembalikan true, tetapib
mengandung elemen tidak masuka
.Saya memposting banyak hal dalam komentar saya pikir itu menjamin jawabannya sendiri.
Seperti yang dikatakan semua orang di sini, menggunakan equals () tergantung pada urutannya. Jika Anda tidak peduli tentang pesanan, Anda memiliki 3 opsi.
Pilihan 1
Gunakan
containsAll()
. Opsi ini tidak ideal, menurut saya, karena ia menawarkan kinerja kasus terburuk, O (n ^ 2).pilihan 2
Ada dua variasi untuk ini:
2a) Jika Anda tidak peduli tentang menjaga urutan daftar Anda ... gunakan
Collections.sort()
di kedua daftar. Kemudian gunakanequals()
. Ini adalah O (nlogn), karena Anda melakukan dua macam, dan kemudian perbandingan O (n).2b) Jika Anda perlu mempertahankan urutan daftar, Anda dapat menyalin kedua daftar terlebih dahulu. MAKA Anda dapat menggunakan solusi 2a pada kedua daftar yang disalin. Namun ini mungkin tidak menarik jika menyalin sangat mahal.
Ini mengarah ke:
Opsi 3
Jika persyaratan Anda sama dengan bagian 2b , tetapi menyalin terlalu mahal. Anda dapat menggunakan TreeSet untuk melakukan penyortiran untuk Anda. Buang setiap daftar ke TreeSet sendiri. Ini akan disortir dalam set, dan daftar asli akan tetap utuh. Kemudian lakukan
equals()
perbandingan pada keduanyaTreeSet
. TheTreeSets
s dapat dibangun dalam O (nlogn) waktu, danequals()
adalah O (n).Ambil pilihanmu :-).
EDIT: Saya hampir lupa peringatan yang sama yangditunjukkan Laurence Gonsalves . Implementasi TreeSet akan menghilangkan duplikat. Jika Anda peduli tentang duplikat, Anda akan membutuhkan semacam multiset yang diurutkan.
sumber
a.containsAll(b) && b.containsAll(a)
Jika Anda menggunakan (atau senang menggunakan) Koleksi Apache Commons, Anda dapat menggunakan CollectionUtils.isEqualCollection yang "mengembalikan true jika Koleksi yang diberikan mengandung elemen yang persis sama dengan kardinalitas yang persis sama."
sumber
Sangat terlambat ke pesta tetapi ingin menambahkan cek aman nol ini:
sumber
Saya tahu ini adalah utas lama, tetapi tidak ada jawaban lain yang sepenuhnya memecahkan kasus penggunaan saya (saya kira Guava Multiset mungkin melakukan hal yang sama, tetapi tidak ada contoh di sini). Maafkan pemformatan saya. Saya masih baru untuk memposting di stack stack. Selain itu beri tahu saya jika ada kesalahan
Katakanlah Anda memiliki
List<T>
a danList<T>
b dan Anda ingin memeriksa apakah mereka sama dengan kondisi berikut:1) O (n) waktu berjalan yang diharapkan
2) Kesetaraan didefinisikan sebagai: Untuk semua elemen dalam a atau b, berapa kali elemen terjadi dalam a sama dengan berapa kali elemen tersebut terjadi dalam b. Elemen kesetaraan didefinisikan sebagai T.equals ()
Waktu berjalan adalah O (n) karena kita melakukan penyisipan O (2 * n) ke dalam hashmap dan O (3 * n) memilih hashmap. Saya belum sepenuhnya menguji kode ini, jadi waspadalah :)
sumber
Coba versi ini yang tidak membutuhkan urutan yang sama tetapi mendukung memiliki kelipatan dari nilai yang sama. Mereka cocok hanya jika masing-masing memiliki jumlah nilai yang sama.
sumber
Metode equals pada Daftar akan melakukan ini, Daftar diperintahkan, sehingga untuk menjadi sama dua Daftar harus memiliki elemen yang sama dalam urutan yang sama.
sumber
Solusi untuk kasus ketika dua daftar memiliki elemen yang sama, tetapi urutannya berbeda:
sumber
removeAll()
alih-alihcontainsAll()
(pemahaman saya adalah bahwa jika listTwo berisi duplikat yang terkandung hanya sekali dalam listOne, pendekatan containAll () akan melaporkan daftar dengan benar sebagai yang sama).Jawaban Tom sangat bagus. Saya setuju sepenuhnya dengan jawabannya!
Aspek yang menarik dari pertanyaan ini adalah, apakah Anda memerlukan
List
jenis itu sendiri dan urutan bawaannya.Jika tidak, Anda dapat menurunkan
Iterable
atauCollection
yang memberi Anda beberapa fleksibilitas dalam melewati struktur data yang diurutkan pada waktu penyisipan, daripada pada saat Anda ingin memeriksa.Jika pesanan tidak pernah penting (dan Anda tidak memiliki duplikat elemen) mempertimbangkan menggunakan
Set
.Jika pesanan penting tetapi ditentukan oleh waktu penyisipan (dan Anda tidak memiliki duplikat) pertimbangkan
LinkedHashSet
yang seperti TreeSet tetapi dipesan berdasarkan waktu penyisipan (duplikat tidak dihitung). Ini juga memberi AndaO(1)
akses yang diamortisasiO(log n)
.sumber
Kode sampel:
sumber
Selain jawaban Laurence, jika Anda juga ingin menjadikannya nol-aman:
sumber
if (list1 == null) return list2==null; if (list2 == null) return false;
Jika daftar Anda mengandung MyClass Kelas kustom, kelas ini harus menimpa
equals
fungsi.Catatan: jika Anda ingin menguji sama dengan pada java.util.Set daripada a
java.util.List
, maka objek Anda harus menimpahashCode
fungsi.sumber
List.equals ()
http://java.sun.com/j2se/1.5/docs/api/java/util/List.html#equals(java.lang.Object)
sumber
Anda dapat menggunakan perpustakaan Apache.apache.commons.collections: http://commons.apache.org/collections/apidocs/org/apache/commons/collections/ListUtils.html
sumber
Periksa kedua daftar bukan nol. Jika ukurannya berbeda, maka daftar ini tidak sama. Buat peta yang terdiri dari elemen daftar sebagai kunci dan pengulangannya sebagai nilai dan bandingkan peta.
Asumsi, jika kedua daftar adalah nol, saya menganggapnya sama.
Harap dicatat, metode yang sama harus didefinisikan dengan benar untuk objek-objek ini. https://stackoverflow.com/a/24814634/4587961
sumber
[x, x, y]
Vs[x, y, y]
akan kembali benar dengan implementasi Anda.Itu tergantung pada kelas Daftar konkret apa yang Anda gunakan. Kelas abstrak AbstractCollection memiliki metode yang disebut berisiAll (Koleksi) yang mengambil koleksi lain (Daftar adalah koleksi) dan:
Jadi jika ArrayList dilewatkan, Anda dapat memanggil metode ini untuk melihat apakah mereka persis sama.
Alasan untuk containAll () adalah karena iterasi melalui daftar pertama mencari kecocokan di daftar kedua. Jadi jika mereka salah urutan sama dengan () tidak akan mengambilnya.
EDIT: Saya hanya ingin memberikan komentar di sini tentang waktu berjalan diamortisasi melakukan berbagai opsi yang ditawarkan. Apakah waktu berjalan itu penting? Tentu. Apakah itu satu-satunya hal yang harus Anda pertimbangkan? Tidak.
Biaya menyalin SETIAP elemen tunggal dari daftar Anda ke daftar lain membutuhkan waktu, dan itu juga memakan banyak memori (secara efektif menggandakan memori yang Anda gunakan).
Jadi jika memori di JVM Anda tidak menjadi masalah (yang seharusnya pada umumnya) maka Anda masih perlu mempertimbangkan waktu yang diperlukan untuk menyalin setiap elemen dari dua daftar menjadi dua TreeSets. Ingat itu menyortir setiap elemen saat memasuki mereka.
Saran terakhir saya? Anda perlu mempertimbangkan kumpulan data Anda dan berapa banyak elemen yang Anda miliki dalam kumpulan data Anda, dan juga seberapa besar setiap objek dalam kumpulan data Anda sebelum Anda dapat membuat keputusan yang baik di sini. Main-main dengan mereka, buat satu jalan sekali dan lihat mana yang berjalan lebih cepat. Ini latihan yang bagus.
sumber