Bagaimana cara saya PriorityQueue
memilah apa yang saya inginkan?
Juga, apakah ada perbedaan antara metode offer
dan add
metode?
sumber
Bagaimana cara saya PriorityQueue
memilah apa yang saya inginkan?
Juga, apakah ada perbedaan antara metode offer
dan add
metode?
Gunakan overload konstruktor yang membutuhkan Comparator<? super E> comparator
dan lulus dalam pembanding yang membandingkan dengan cara yang sesuai untuk pesanan sortir Anda. Jika Anda memberikan contoh bagaimana Anda ingin menyortir, kami dapat memberikan beberapa kode sampel untuk mengimplementasikan komparator jika Anda tidak yakin. (Ini cukup mudah.)
Seperti yang telah dikatakan di tempat lain: offer
dan add
hanya implementasi metode antarmuka yang berbeda. Di sumber JDK yang saya dapat, add
panggilan offer
. Meskipun add
dan offer
memiliki perilaku yang berpotensi berbeda secara umum karena kemampuan untuk offer
menunjukkan bahwa nilai tidak dapat ditambahkan karena batasan ukuran, perbedaan ini tidak relevan di PriorityQueue
mana tidak terikat.
Berikut adalah contoh penyortiran antrian berdasarkan panjang string:
// Test.java
import java.util.Comparator;
import java.util.PriorityQueue;
public class Test {
public static void main(String[] args) {
Comparator<String> comparator = new StringLengthComparator();
PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator);
queue.add("short");
queue.add("very long indeed");
queue.add("medium");
while (queue.size() != 0) {
System.out.println(queue.remove());
}
}
}
// StringLengthComparator.java
import java.util.Comparator;
public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String x, String y) {
// Assume neither string is null. Real code should
// probably be more robust
// You could also just return x.length() - y.length(),
// which would be more efficient.
if (x.length() < y.length()) {
return -1;
}
if (x.length() > y.length()) {
return 1;
}
return 0;
}
}
Berikut hasilnya:
pendek
medium
memang sangat lama
compare
implementasinya sajareturn x.length() - y.length()
? (Menghindari prediksi cabang)add()
untuk operasi penambahan, makaremove()
terasa masuk akal; jika saya menggunakanoffer()
saya mungkin akan menggunakanpoll()
... tapi itu hanya preferensi pribadi.Solusi Java 8
Kita dapat menggunakan
lambda expression
ataumethod reference
memperkenalkan di Java 8. Jika kita memiliki beberapa nilai String yang disimpan dalam Antrian Prioritas (memiliki kapasitas 5) kami dapat menyediakan komparator sebaris (berdasarkan panjang String):Menggunakan ekspresi lambda
Menggunakan referensi Metode
Maka kita dapat menggunakan salah satu dari mereka sebagai:
Ini akan mencetak:
Untuk membalikkan urutan (untuk mengubahnya ke antrian prioritas maksimum) cukup ubah urutan dalam pembanding inline atau gunakan
reversed
sebagai:Kita juga bisa menggunakan
Collections.reverseOrder
:Jadi kita dapat melihat bahwa
Collections.reverseOrder
kelebihan beban mengambil pembanding yang dapat berguna untuk objek kustom. Thereversed
sebenarnya menggunakanCollections.reverseOrder
:offer () vs add ()
Sesuai dok
Saat menggunakan antrian terbatas kapasitas, penawaran () biasanya lebih disukai untuk ditambahkan (), yang bisa gagal memasukkan elemen hanya dengan melemparkan pengecualian. Dan PriorityQueue adalah antrian prioritas tanpa batas berdasarkan tumpukan prioritas.
sumber
5
menunjukkan kapasitas awal antrian?Cukup berikan
Comparator
kepada konstruktor :Satu-satunya perbedaan antara
offer
danadd
adalah antarmuka mereka.offer
milikQueue<E>
, sedangkan padaadd
awalnya terlihat diCollection<E>
antarmuka. Selain kedua metode melakukan hal yang persis sama - masukkan elemen yang ditentukan ke dalam antrian prioritas.sumber
dari Antrian API :
sumber
tidak berbeda, seperti yang dinyatakan dalam javadoc:
sumber
Hanya untuk menjawab pertanyaan
add()
vsoffer()
(karena yang lain menjawab dengan sempurna imo, dan ini mungkin tidak):Menurut JavaDoc pada antarmuka Antrian , "Metode penawaran menyisipkan elemen jika mungkin, jika tidak mengembalikan false. Ini berbeda dari metode Collection.add, yang dapat gagal menambahkan elemen hanya dengan melemparkan pengecualian yang tidak dicentang. Metode penawaran dirancang untuk gunakan ketika kegagalan adalah normal, daripada kejadian luar biasa, misalnya, dalam antrian berkapasitas tetap (atau "terikat"). "
Itu berarti jika Anda dapat menambahkan elemen (yang harus selalu menjadi kasus dalam PriorityQueue), mereka bekerja persis sama. Tetapi jika Anda tidak dapat menambahkan elemen,
offer()
akan memberi Anda pengembalian yang bagus dan cantikfalse
, sambiladd()
melempar pengecualian yang tidak diperiksa dan tidak dicentang yang tidak Anda inginkan dalam kode Anda. Jika kegagalan untuk menambah berarti kode berfungsi sebagaimana dimaksud dan / atau itu adalah sesuatu yang akan Anda periksa secara normal, gunakanoffer()
. Jika kegagalan untuk menambahkan berarti ada sesuatu yang rusak, gunakanadd()
dan tangani pengecualian yang dihasilkan yang dilemparkan sesuai dengan spesifikasi antarmuka Collection .Keduanya diimplementasikan dengan cara ini untuk memenuhi kontrak pada antarmuka Antrian yang menentukan
offer()
gagal dengan mengembalikanfalse
( metode yang disukai dalam antrian kapasitas terbatas ) dan juga mempertahankan kontrak pada antarmuka Koleksi yang menentukanadd()
selalu gagal dengan melemparkan pengecualian .Pokoknya, harapan yang menjelaskan setidaknya bagian dari pertanyaan itu.
sumber
Di sini, Kami dapat mendefinisikan komparator yang ditentukan pengguna:
Perbedaan antara metode menawarkan dan menambahkan: tautan
sumber
Lulus a
Comparator
. Isi jenis yang Anda inginkan di tempatT
Menggunakan lambdas (Java 8+):
Cara klasik, menggunakan kelas anonim:
Untuk mengurutkan dalam urutan terbalik, cukup tukar e1, e2.
sumber
Saya juga bertanya-tanya tentang pesanan cetak. Pertimbangkan kasus ini, misalnya:
Untuk antrian prioritas:
Kode ini:
dapat mencetak berbeda dari:
Saya menemukan jawaban dari diskusi di forum lain , di mana pengguna berkata, "metode tawaran () / tambahkan () hanya memasukkan elemen ke dalam antrian. Jika Anda ingin pesanan yang dapat diprediksi, Anda harus menggunakan mengintip / polling yang mengembalikan kepala. dari antrian. "
sumber
Sebagai alternatif untuk menggunakan
Comparator
, Anda juga dapat memiliki kelas yang Anda gunakan dalamPriorityQueue
implementComparable
Anda (dan dengan demikian menimpacompareTo
metode tersebut).Perhatikan bahwa umumnya hanya baik digunakan
Comparable
alih-alihComparator
jika urutan itu adalah urutan intuitif objek - jika, misalnya, Anda memiliki kasus penggunaan untuk mengurutkanPerson
objek berdasarkan usia, mungkin yang terbaik adalah hanya menggunakanComparator
saja.Keluaran:
sumber
Antrian Prioritas memiliki beberapa prioritas yang ditetapkan untuk setiap elemen, Elemen dengan prioritas tertinggi muncul di Top Of Queue. Sekarang, itu tergantung pada Anda bagaimana Anda ingin prioritas ditetapkan untuk masing-masing elemen. Jika tidak, Java akan melakukannya dengan cara default. Elemen dengan nilai paling rendah diberikan prioritas tertinggi dan dengan demikian dihapus dari antrian terlebih dahulu. Jika ada beberapa elemen dengan prioritas tertinggi yang sama, maka ikatnya putus secara sewenang-wenang. Anda juga dapat menentukan pemesanan menggunakan Pembanding di konstruktor
PriorityQueue(initialCapacity, comparator)
Kode Contoh:
Keluaran:
Selain itu, Anda juga dapat menentukan Pembanding Kustom:
sumber
Berikut adalah contoh sederhana yang dapat Anda gunakan untuk pembelajaran awal:
sumber