Apakah ada alasan bagus mengapa tidak ada Pair<L,R>
di Jawa? Apa yang akan setara dengan konstruk C ++ ini? Saya lebih suka menghindari mengimplementasikan saya sendiri.
Tampaknya 1.6 menyediakan sesuatu yang serupa ( AbstractMap.SimpleEntry<K,V>
), tetapi ini terlihat cukup berbelit-belit.
AbstractMap.SimpleEntry
berbelit - belit?Jawaban:
Dalam sebuah utas
comp.lang.java.help
, Hunter Gratzner memberikan beberapa argumen yang menentang keberadaanPair
konstruk di Jawa. Argumen utama adalah bahwa suatu kelasPair
tidak menyampaikan semantik tentang hubungan antara dua nilai (bagaimana Anda tahu apa arti "pertama" dan "kedua"?).Praktik yang lebih baik adalah menulis kelas yang sangat sederhana, seperti yang diusulkan Mike, untuk setiap aplikasi yang Anda buat dari
Pair
kelas tersebut.Map.Entry
adalah contoh dari pasangan yang membawa maknanya dalam namanya.Singkatnya, menurut saya lebih baik memiliki kelas
Position(x,y)
, kelasRange(begin,end)
dan kelasEntry(key,value)
daripada generikPair(first,second)
yang tidak memberi tahu saya apa-apa tentang apa yang seharusnya dilakukan.sumber
Ini Jawa. Anda harus membuat kelas Pair Anda sendiri yang disesuaikan dengan kelas deskriptif dan nama bidang, dan tidak keberatan bahwa Anda akan menemukan kembali roda dengan menulis kode hash () / equals () atau menerapkan Sebanding lagi dan lagi.
sumber
SimpleImmutableEntry
Kelas Pair yang kompatibel dengan HashMap:
sumber
super()
mengeluarkannya. Biasanya saya hanya memotongnya jika itu opsional, seperti di sini.Pasangan terpendek yang bisa saya ajukan adalah yang berikut, menggunakan Lombok :
Ia memiliki semua manfaat dari jawaban dari @arturh (kecuali komparabilitas), itu memiliki
hashCode
,equals
,toString
dan statis “konstruktor”.sumber
Apache Commons Lang 3.0+ memiliki beberapa kelas Pair: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html
sumber
Cara lain untuk mengimplementasikan Pair with.
Pabrik sederhana sehingga Anda tidak perlu menyediakan jenisnya. misalnya Pair.of ("halo", 1);
sumber
of
. Ini mengingatkan pada koleksi abadi Guava Google .o1
untukComparable
, meskipun tidak ada menunjukkan hal itu akan benar-benar mengimplementasikan antarmuka yang. Jika itu merupakan persyaratan,FIRST
parameter type seharusnyaFIRST extends Comparable<?>
.Bagaimana dengan http://www.javatuples.org/index.html Saya merasa sangat berguna.
The javatuples menawarkan kepada Anda kelas tuple dari satu hingga sepuluh elemen:
sumber
Pair
dan bisa membayangkan untuk menggunakanTriplet
mungkin sekali setiap 50 tahun. Sekarang saya menggunakan Lombok dan membuat kelas 4-garis kecil setiap kali saya membutuhkan pasangan. Jadi "10 terlalu banyak" adalah tepat.Bottom (0 element)
kelas? :)Tergantung pada apa Anda ingin menggunakannya. Alasan khas untuk melakukannya adalah untuk beralih ke peta, yang Anda lakukan ini (Java 5+):
sumber
Android menyediakan
Pair
kelas ( http://developer.android.com/reference/android/util/Pair.html ), di sini implementasinya:sumber
Objects.equal(..)
membutuhkan perpustakaan Guava.Objects.equals(...)
yang sudah ada di Jawa sejak 2011 (1.7).Masalah terbesar mungkin adalah bahwa seseorang tidak dapat memastikan ketidakmampuan pada A dan B (lihat Bagaimana memastikan bahwa parameter tipe tidak dapat diubah ) sehingga
hashCode()
dapat memberikan hasil yang tidak konsisten untuk Pasangan yang sama setelah dimasukkan dalam koleksi misalnya (ini akan memberikan perilaku yang tidak ditentukan) , lihat Menentukan persamaan dalam hal bidang yang bisa diubah ). Untuk kelas Pair tertentu (non generik), programmer dapat memastikan imutabilitas dengan hati-hati memilih A dan B agar tidak berubah.Lagi pula, menghapus peringatan generik dari jawaban @ PeterLawrey (java 1.7):
Tambahan / koreksi banyak diterima :) Secara khusus saya tidak yakin tentang penggunaan saya
Pair<?, ?>
.Untuk info lebih lanjut tentang mengapa sintaks ini lihat Memastikan bahwa objek mengimplementasikan Sebanding dan untuk penjelasan rinci Bagaimana menerapkan
max(Comparable a, Comparable b)
fungsi generik di Jawa?sumber
Menurut pendapat saya, tidak ada pasangan di Jawa karena, jika Anda ingin menambahkan fungsionalitas tambahan langsung pada pasangan (misalnya Sebanding), Anda harus mengikat jenisnya. Dalam C ++, kami hanya tidak peduli, dan jika jenis yang menyusun pasangan tidak memiliki
operator <
, makapair::operator <
tidak akan mengkompilasi juga.Contoh Sebanding dengan tanpa batas:
Contoh Comparable with compile-time check untuk apakah argumen tipe sebanding:
Ini bagus, tapi kali ini Anda mungkin tidak menggunakan tipe yang tidak sebanding sebagai argumen tipe di Pair. Seseorang dapat menggunakan banyak Pembanding untuk Pasangan di beberapa kelas utilitas, tetapi orang-orang C ++ mungkin tidak mendapatkannya. Cara lain adalah dengan menulis banyak kelas dalam hierarki tipe dengan batasan berbeda pada argumen tipe, tetapi ada terlalu banyak batasan yang mungkin dan kombinasinya ...
sumber
JavaFX (yang dibundel dengan Java 8) memiliki kelas Pair <A, B>
sumber
hashCode()
. Perhatikan bahwa Java sendiri tidak memanggil metode ini. Ini untuk kode pengguna, termasuk perpustakaan.Seperti yang telah dinyatakan oleh banyak orang lain, itu benar-benar tergantung pada use case apakah kelas Pair berguna atau tidak.
Saya pikir untuk fungsi pembantu pribadi, adalah benar-benar sah untuk menggunakan kelas Pair jika itu membuat kode Anda lebih mudah dibaca dan tidak sebanding dengan upaya menciptakan kelas nilai lain dengan semua kode pelat ketelnya.
Di sisi lain, jika level abstraksi Anda mengharuskan Anda untuk mendokumentasikan semantik kelas yang berisi dua objek atau nilai, maka Anda harus menulis kelas untuknya. Biasanya itu masalahnya jika data adalah objek bisnis.
Seperti biasa, itu membutuhkan penilaian yang terampil.
Untuk pertanyaan kedua Anda, saya merekomendasikan kelas Pair dari perpustakaan Apache Commons. Itu mungkin dianggap sebagai pustaka standar yang diperluas untuk Java:
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html
Anda mungkin juga ingin melihat di Apache Commons ' EqualsBuilder , HashCodeBuilder dan ToStringBuilder yang menyederhanakan penulisan kelas nilai untuk objek bisnis Anda.
sumber
Anda dapat menggunakan kelas utilitas javafx,
Pair
yang melayani tujuan yang sama dengan pasangan <> di c ++. https://docs.oracle.com/javafx/2/api/javafx/util/Pair.htmlsumber
Kabar Baik
JavaFX
memiliki nilai kunci Pair.tambahkan saja javafx sebagai ketergantungan dan impor
javafx.util.Pair
;dan gunakan hanya seperti pada
c++
.misalnya
sumber
Antarmuka Map.Entry datang cukup dekat dengan pasangan c ++. Lihatlah implementasi konkret, seperti AbstractMap.SimpleEntry dan AbstractMap.SimpleImmutableEntry Item pertama adalah getKey () dan yang kedua adalah getValue ().
sumber
sumber
Menurut sifat bahasa Jawa, saya kira orang tidak benar-benar memerlukan
Pair
, antarmuka biasanya apa yang mereka butuhkan. Berikut ini sebuah contoh:Jadi, ketika orang ingin mengembalikan dua nilai, mereka dapat melakukan hal berikut:
Ini adalah solusi yang cukup ringan, dan menjawab pertanyaan "Apa itu semantik dari
Pair<L,R>
?". Jawabannya adalah, ini adalah antarmuka yang dibangun dengan dua (mungkin berbeda) jenis, dan memiliki metode untuk mengembalikan masing-masing. Terserah Anda untuk menambahkan semantik lebih lanjut. Misalnya, jika Anda menggunakan Posisi dan BENAR-BENAR ingin menunjukkannya dalam kode Anda, Anda dapat menentukanPositionX
danPositionY
yang berisiInteger
, untuk membuat aPair<PositionX,PositionY>
. Jika JSR 308 tersedia, Anda juga dapat menggunakannyaPair<@PositionX Integer, @PositionY Ingeger>
untuk menyederhanakannya.EDIT: Satu hal yang saya harus tunjukkan di sini adalah bahwa definisi di atas secara eksplisit berkaitan dengan nama parameter type dan nama metode. Ini adalah jawaban bagi mereka yang berpendapat bahwa
Pair
kurangnya informasi semantik. Sebenarnya, metode inigetL
berarti "beri saya elemen yang sesuai dengan tipe tipe parameter L", yang berarti sesuatu.EDIT: Ini adalah kelas utilitas sederhana yang dapat membuat hidup lebih mudah:
pemakaian:
sumber
equals
,hashCode
dantoString
?toString
Anda perlu lebih banyak pengetahuan tentang hubungan antara kedua bidang.class
mungkin lebih baik daripada hanyainterface
karena dapat mengimplementasikan hal-hal ini.Meskipun secara sintaksis serupa, Java dan C ++ memiliki paradigma yang sangat berbeda. Menulis C ++ seperti Java adalah C ++ yang buruk, dan menulis Java seperti C ++ adalah Java yang buruk.
Dengan IDE berbasis refleksi seperti Eclipse, menulis fungsionalitas kelas "pasangan" dengan cepat dan sederhana. Buat kelas, tentukan dua bidang, gunakan berbagai opsi menu "Hasilkan XX" untuk mengisi kelas dalam hitungan detik. Mungkin Anda harus mengetikkan "compareTo" dengan sangat cepat jika Anda menginginkan antarmuka yang sebanding.
Dengan opsi deklarasi / definisi terpisah dalam bahasa, kode generator C ++ tidak begitu baik, jadi menulis sedikit kelas utilitas lebih memakan waktu kebosanan. Karena pasangan adalah templat, Anda tidak perlu membayar untuk fungsi-fungsi yang tidak Anda gunakan, dan fasilitas typedef memungkinkan menetapkan nama ketik yang bermakna ke kode, sehingga keberatan tentang "tidak ada semantik" tidak benar-benar bertahan.
sumber
Pasangan akan menjadi hal yang baik, untuk menjadi unit konstruksi dasar untuk obat generik yang kompleks, misalnya, ini dari kode saya:
Sama seperti Haskell's Tuple
sumber
Pair
optimal karena tidak ada semantik khusus. Memiliki nama yang jelas untuk konsep yang jelas itu baik, tetapi mencari nama di mana "pertama" dan "kedua" bekerja dengan baik tidak.Simple way Object [] - dapat digunakan sebagai tuple dimensi
sumber
Untuk bahasa pemrograman seperti Java, struktur data alternatif yang digunakan oleh sebagian besar programmer untuk mewakili pasangan seperti struktur data adalah dua larik, dan data diakses melalui indeks yang sama
contoh: http://www-igm.univ-mlv.fr/~lecroq/string/node8.html#SECTION0080
Ini tidak ideal karena data harus diikat bersama, tetapi juga ternyata cukup murah. Juga, jika use case Anda menuntut penyimpanan koordinat maka lebih baik untuk membangun struktur data Anda sendiri.
Saya memiliki sesuatu seperti ini di perpustakaan saya
sumber
Anda dapat menggunakan perpustakaan AutoValue Google - https://github.com/google/auto/tree/master/value .
Anda membuat kelas abstrak yang sangat kecil dan membubuhi keterangan dengan @AutoValue dan prosesor anotasi menghasilkan kelas konkret untuk Anda yang memiliki nilai semantik.
sumber
Berikut adalah beberapa perpustakaan yang memiliki beberapa tingkat tupel untuk kenyamanan Anda:
Perpustakaan lain telah disebutkan mengandung setidaknya
Pair
tupel.Khususnya, dalam konteks pemrograman fungsional yang menggunakan banyak pengetikan struktural, daripada pengetikan nominal ( seperti yang disarankan dalam jawaban yang diterima ), perpustakaan dan tupel mereka sangat berguna.
sumber
Brian Goetz, Paul Sandoz dan Stuart Marks menjelaskan mengapa selama sesi QA di Devoxx'14.
Memiliki kelas pasangan generik di perpustakaan standar akan berubah menjadi utang teknis setelah jenis nilai diperkenalkan.
Lihat juga: Apakah Java SE 8 memiliki Pairs atau Tuples?
sumber
implementasi lombok singkat lainnya
sumber
Saya perhatikan semua implementasi Pair berserakan di sini atribut yang berarti urutan dua nilai. Ketika saya memikirkan pasangan, saya memikirkan kombinasi dua item di mana urutan keduanya tidak penting. Inilah implementasi pasangan berpasangan yang tidak tertata, dengan
hashCode
danequals
menimpa untuk memastikan perilaku yang diinginkan dalam koleksi. Juga dapat dikloning.Implementasi ini telah diuji unit dengan benar dan penggunaan dalam Set dan Peta telah dicoba.
Perhatikan bahwa saya tidak mengklaim untuk melepaskan ini di domain publik. Ini adalah kode yang baru saja saya tulis untuk digunakan dalam aplikasi, jadi jika Anda akan menggunakannya, jangan membuat salinan langsung dan mengacaukan dengan komentar dan nama sedikit. Tangkap maksudku?
sumber
Jika ada yang menginginkan versi mati-sederhana dan mudah digunakan, saya membuatnya tersedia di https://github.com/lfac-pt/Java-Pair . Juga, perbaikan sangat disambut baik!
sumber
com.sun.tools.javac.util.Pair adalah implementasi sederhana dari suatu pasangan. Itu dapat ditemukan di jdk1.7.0_51 \ lib \ tools.jar.
Selain dari org.apache.commons.lang3.tuple.Pair, ini bukan hanya sebuah antarmuka.
sumber
penggunaan:
Abadi, hanya sepasang!
sumber
Pair<Object, Object> pair = Pair.createPair("abc", "def")
tetapi saya pikir seseorang perlu menulisPair.createPair((Object)"abc", (Object)"def")
dengan kode Anda?@SuppressWarnings("unchecked") public static <K, V, X, Y> Pair<X, Y> createPair(K key, V value) { return new Pair<X, Y>((X) key, (Y) value); }
tetapi saya tidak tahu apakah itu praktik yang baiknew Pair<Object, Object>("abc", "def")
adalah yang paling dapat diandalkan dalam percobaan saya.