मैं कैसे प्राप्त करूं PriorityQueue
पर सॉर्ट करने के जो मैं चाहता हूं कि मैं उस पर सॉर्ट करूं?
मैं कैसे प्राप्त करूं PriorityQueue
पर सॉर्ट करने के जो मैं चाहता हूं कि मैं उस पर सॉर्ट करूं?
जवाबों:
कंस्ट्रक्टर ओवरलोड का उपयोग करें जो ए Comparator<? super E> comparator
एक तुलनित्र में गुजरता और पास होता है जो आपके सॉर्ट क्रम के लिए उपयुक्त तरीके से तुलना करता है। यदि आप इस बात का उदाहरण देते हैं कि आप कैसे छांटना चाहते हैं, तो यदि आप निश्चित नहीं हैं तो हम तुलनित्र को लागू करने के लिए कुछ नमूना कोड प्रदान कर सकते हैं। (हालांकि यह बहुत सीधा है।)
जैसा कि कहीं offer
और कहा गया है: और add
बस अलग-अलग इंटरफ़ेस विधि कार्यान्वयन हैं। JDK स्रोत में मुझे add
कॉल मिला है offer
। हालांकि add
और offer
है संभवतः के लिए क्षमता के लिए सामान्य कारण में अलग व्यवहार offer
संकेत मिलता है कि मूल्य आकार सीमाओं के कारण नहीं जोड़ा जा सकता, इस अंतर में अप्रासंगिक है PriorityQueue
जो असीमित है।
यहां स्ट्रिंग लेंथ द्वारा छंटनी प्राथमिकता कतार का एक उदाहरण दिया गया है:
// 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;
}
}
यहाँ उत्पादन है:
कम
मध्यम
वास्तव में बहुत लंबा है
compare
सिर्फ कार्यान्वयन नहीं होना चाहिए return x.length() - y.length()
? (अवॉड्र्स ब्रांच प्रेडिक्शन)
add()
जोड़ने के संचालन के लिए उपयोग कर रहे हैं , तो remove()
समझदार लगता है; अगर मैं उपयोग कर offer()
रहा था तो मैं शायद उपयोग करूंगा poll()
... लेकिन यह सिर्फ एक व्यक्तिगत प्राथमिकता है।
हम जावा 8. का उपयोग कर सकते हैं lambda expression
या method reference
शुरू कर सकते हैं । यदि हमारे पास कुछ प्राथमिकताएँ हैं, जिन्हें प्राथमिकता कतार (क्षमता 5) में संग्रहीत किया जाता है, तो हम इनलाइन तुलनित्र प्रदान कर सकते हैं (स्ट्रिंग की लंबाई के आधार पर):
लंबोदर अभिव्यक्ति का उपयोग करना
PriorityQueue<String> pq=
new PriorityQueue<String>(5,(a,b) -> a.length() - b.length());
विधि संदर्भ का उपयोग करना
PriorityQueue<String> pq=
new PriorityQueue<String>(5, Comparator.comparing(String::length));
फिर हम उनमें से किसी का भी उपयोग कर सकते हैं:
public static void main(String[] args) {
PriorityQueue<String> pq=
new PriorityQueue<String>(5, (a,b) -> a.length() - b.length());
// or pq = new PriorityQueue<String>(5, Comparator.comparing(String::length));
pq.add("Apple");
pq.add("PineApple");
pq.add("Custard Apple");
while (pq.size() != 0)
{
System.out.println(pq.remove());
}
}
यह प्रिंट करेगा:
Apple
PineApple
Custard Apple
आदेश को उलटने के लिए (इसे अधिकतम-प्राथमिकता कतार में बदलने के लिए) बस क्रम इनलाइन तुलनित्र को बदल दें या निम्नानुसार उपयोग करें reversed
:
PriorityQueue<String> pq = new PriorityQueue<String>(5,
Comparator.comparing(String::length).reversed());
हम भी उपयोग कर सकते हैं Collections.reverseOrder
:
PriorityQueue<Integer> pqInt = new PriorityQueue<>(10, Collections.reverseOrder());
PriorityQueue<String> pq = new PriorityQueue<String>(5,
Collections.reverseOrder(Comparator.comparing(String::length))
इसलिए हम देख सकते हैं कि Collections.reverseOrder
तुलनित्र लेने के लिए अतिभारित है जो कस्टम ऑब्जेक्ट्स के लिए उपयोगी हो सकता है। reversed
वास्तव में उपयोग करता है Collections.reverseOrder
:
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
डॉक्टर के अनुसार
यदि संभव हो तो प्रस्ताव विधि एक तत्व सम्मिलित करती है, अन्यथा झूठे वापस लौटती है। यह Collection.add विधि से भिन्न है, जो केवल अनियंत्रित अपवाद को फेंककर एक तत्व को जोड़ने में विफल हो सकता है। ऑफ़र विधि को उपयोग के लिए डिज़ाइन किया गया है जब विफलता सामान्य घटना के बजाय सामान्य है, उदाहरण के लिए, निश्चित-क्षमता (या "बंधे") कतारों में।
क्षमता-प्रतिबंधित कतार का उपयोग करते समय, ऑफ़र () आम तौर पर जोड़ने के लिए बेहतर होता है (), जो केवल एक अपवाद फेंककर एक तत्व सम्मिलित करने में विफल हो सकता है। और प्रायोरिटी क्यू एक प्राथमिकता वाले ढेर पर आधारित एक अनबाउंड प्राथमिकता कतार है।
5
कतार की शुरुआती क्षमता को दर्शाता है?
बस कंस्ट्रक्टर केComparator
लिए उपयुक्त पास :
PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
के बीच एकमात्र अंतर है offer
और add
वे जिस इंटरफ़ेस से संबंधित हैं। offer
से संबंधित है Queue<E>
, जबकि add
मूल रूप से Collection<E>
इंटरफ़ेस में देखा जाता है। इसके अलावा दोनों विधियां बिल्कुल समान हैं - निर्दिष्ट तत्व को प्राथमिकता कतार में डालें।
से कतार एपीआई :
यदि संभव हो तो प्रस्ताव विधि एक तत्व सम्मिलित करती है, अन्यथा झूठे वापस लौटती है। यह Collection.add विधि से भिन्न है, जो केवल अनियंत्रित अपवाद को फेंककर एक तत्व को जोड़ने में विफल हो सकता है। ऑफ़र विधि को उपयोग के लिए डिज़ाइन किया गया है जब विफलता सामान्य घटना के बजाय सामान्य है, उदाहरण के लिए, निश्चित-क्षमता (या "बंधे") कतारों में।
बस add()
बनाम offer()
प्रश्न का उत्तर देने के लिए (चूंकि दूसरा पूरी तरह से उत्तर दिया गया है, और यह नहीं हो सकता है):
इंटरफ़ेस कतार पर JavaDoc के अनुसार , "ऑफ़र विधि यदि संभव हो तो एक तत्व सम्मिलित करता है, अन्यथा गलत तरीके से लौटता है। यह Collection.add विधि से भिन्न होता है, जो केवल अनियंत्रित अपवाद को फेंककर एक तत्व को जोड़ने में विफल हो सकता है। ऑफ़र विधि के लिए डिज़ाइन किया गया है। जब असफलता एक सामान्य घटना है, तो असाधारण घटना के बजाय, उदाहरण के लिए, निश्चित-क्षमता (या "बाध्य") कतारों में उपयोग करें। "
इसका मतलब है कि यदि आप तत्व जोड़ सकते हैं (जो कि प्रायोरिटी क्यू में होना चाहिए), तो वे ठीक उसी तरह काम करते हैं। लेकिन अगर आप तत्व नहीं जोड़ सकते हैं, offer()
तो आपको एक अच्छा और सुंदर false
रिटर्न देगा, जबकि add()
एक गंदा अनियंत्रित अपवाद फेंकता है जिसे आप अपने कोड में नहीं चाहते हैं। यदि जोड़ने में विफलता का अर्थ है कि कोड इरादा के अनुसार काम कर रहा है और / या यह कुछ ऐसा है जिसे आप सामान्य रूप से जांचेंगे, उपयोग करें offer()
। यदि जोड़ने में विफलता का मतलब है कि कुछ टूट गया है, तो संग्रह इंटरफ़ेस के विनिर्देशों केadd()
अनुसार फेंके गए अपवाद को संभालें ।
वे दोनों इस तरह से कतार इंटरफ़ेस पर अनुबंध को पूरा करने के लिए कार्यान्वित किए जाते हैं जो निर्दिष्ट करता है कि offer()
एक false
( क्षमता-प्रतिबंधित कतार में पसंद की गई विधि) को वापस करने में विफल रहता है और संग्रह इंटरफ़ेस पर अनुबंध को बनाए रखना भी निर्दिष्ट करता है add()
जो अपवाद को फेंककर हमेशा विफल रहता है ।
वैसे भी, आशा है कि प्रश्न के कम से कम उस हिस्से को स्पष्ट करता है।
यहां, हम उपयोगकर्ता परिभाषित तुलनित्र को परिभाषित कर सकते हैं:
नीचे कोड:
import java.util.*;
import java.util.Collections;
import java.util.Comparator;
class Checker implements Comparator<String>
{
public int compare(String str1, String str2)
{
if (str1.length() < str2.length()) return -1;
else return 1;
}
}
class Main
{
public static void main(String args[])
{
PriorityQueue<String> queue=new PriorityQueue<String>(5, new Checker());
queue.add("india");
queue.add("bangladesh");
queue.add("pakistan");
while (queue.size() != 0)
{
System.out.printf("%s\n",queue.remove());
}
}
}
आउटपुट:
india pakistan bangladesh
प्रस्ताव और जोड़ने के तरीकों के बीच अंतर: लिंक
इसे पास करो a Comparator
। के स्थान पर अपने इच्छित प्रकार को भरेंT
लैम्ब्डा (जावा 8+) का उपयोग करना:
int initialCapacity = 10;
PriorityQueue<T> pq = new PriorityQueue<>(initialCapacity, (e1, e2) -> { return e1.compareTo(e2); });
अनाम कक्षा का उपयोग करते हुए क्लासिक तरीका:
int initialCapacity = 10;
PriorityQueue<T> pq = new PriorityQueue<>(initialCapacity, new Comparator<T> () {
@Override
public int compare(T e1, T e2) {
return e1.compareTo(e2);
}
});
रिवर्स ऑर्डर में सॉर्ट करने के लिए, बस e1, e2 स्वैप करें।
मैं प्रिंट ऑर्डर के बारे में भी सोच रहा था। इस मामले पर विचार करें, उदाहरण के लिए:
प्राथमिकता कतार के लिए:
PriorityQueue<String> pq3 = new PriorityQueue<String>();
यह कोड:
pq3.offer("a");
pq3.offer("A");
से अलग प्रिंट कर सकते हैं:
String[] sa = {"a", "A"};
for(String s : sa)
pq3.offer(s);
मुझे एक अन्य मंच पर एक चर्चा से जवाब मिला , जहां एक उपयोगकर्ता ने कहा, "प्रस्ताव () / जोड़ें () विधियां केवल कतार में तत्व सम्मिलित करती हैं। यदि आप एक पूर्वानुमान आदेश चाहते हैं तो आपको तिरछी नज़र / पोल का उपयोग करना चाहिए जो सिर को लौटाता है। कतार से
उपयोग करने के विकल्प के रूप में Comparator
, आप वह वर्ग भी रख सकते हैं जिसका आप अपने PriorityQueue
कार्यान्वयनComparable
में उपयोग कर रहे हैं (और इसी compareTo
विधि को ओवरराइड करते हैं )।
ध्यान दें कि आम तौर पर केवल Comparable
इसके बजाय इसका उपयोग करना सबसे अच्छा है Comparator
यदि ऑर्डर करना वस्तु का सहज आदेश है - यदि, उदाहरण के लिए, आपके पास Person
आयु के अनुसार वस्तुओं को सॉर्ट करने के लिए उपयोग मामला है , तो संभवतः Comparator
इसके बजाय इसका उपयोग करना सबसे अच्छा है ।
import java.lang.Comparable;
import java.util.PriorityQueue;
class Test
{
public static void main(String[] args)
{
PriorityQueue<MyClass> queue = new PriorityQueue<MyClass>();
queue.add(new MyClass(2, "short"));
queue.add(new MyClass(2, "very long indeed"));
queue.add(new MyClass(1, "medium"));
queue.add(new MyClass(1, "very long indeed"));
queue.add(new MyClass(2, "medium"));
queue.add(new MyClass(1, "short"));
while (queue.size() != 0)
System.out.println(queue.remove());
}
}
class MyClass implements Comparable<MyClass>
{
int sortFirst;
String sortByLength;
public MyClass(int sortFirst, String sortByLength)
{
this.sortFirst = sortFirst;
this.sortByLength = sortByLength;
}
@Override
public int compareTo(MyClass other)
{
if (sortFirst != other.sortFirst)
return Integer.compare(sortFirst, other.sortFirst);
else
return Integer.compare(sortByLength.length(), other.sortByLength.length());
}
public String toString()
{
return sortFirst + ", " + sortByLength;
}
}
आउटपुट:
1, short
1, medium
1, very long indeed
2, short
2, medium
2, very long indeed
प्राथमिकता कतार में प्रत्येक तत्व को कुछ प्राथमिकता दी गई है, सर्वोच्च प्राथमिकता वाला तत्व कतार के शीर्ष पर दिखाई देता है। अब, यह आप पर निर्भर करता है कि आप प्रत्येक तत्वों को किस प्रकार प्राथमिकता देना चाहते हैं। यदि आप नहीं करते हैं, तो जावा इसे डिफ़ॉल्ट रूप से करेगा। कम से कम मूल्य वाले तत्व को सर्वोच्च प्राथमिकता दी जाती है और इस तरह पहले कतार से हटा दिया जाता है। यदि समान सर्वोच्च प्राथमिकता वाले कई तत्व हैं, तो टाई मनमाने ढंग से टूट जाती है। आप कंस्ट्रक्टर में तुलनित्र का उपयोग करके एक आदेश भी निर्दिष्ट कर सकते हैं PriorityQueue(initialCapacity, comparator)
उदाहरण कोड:
PriorityQueue<String> queue1 = new PriorityQueue<>();
queue1.offer("Oklahoma");
queue1.offer("Indiana");
queue1.offer("Georgia");
queue1.offer("Texas");
System.out.println("Priority queue using Comparable:");
while (queue1.size() > 0) {
System.out.print(queue1.remove() + " ");
}
PriorityQueue<String> queue2 = new PriorityQueue(4, Collections.reverseOrder());
queue2.offer("Oklahoma");
queue2.offer("Indiana");
queue2.offer("Georgia");
queue2.offer("Texas");
System.out.println("\nPriority queue using Comparator:");
while (queue2.size() > 0) {
System.out.print(queue2.remove() + " ");
}
आउटपुट:
Priority queue using Comparable:
Georgia Indiana Oklahoma Texas
Priority queue using Comparator:
Texas Oklahoma Indiana Georgia
और, आप कस्टम तुलनित्र को भी परिभाषित कर सकते हैं:
import java.util.Comparator;
public class StringLengthComparator implements Comparator<String>
{
@Override
public int compare(String x, String y)
{
//Your Own Logic
}
}
यहाँ सरल उदाहरण है जिसे आप प्रारंभिक शिक्षा के लिए उपयोग कर सकते हैं:
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
public class PQExample {
public static void main(String[] args) {
//PriorityQueue with Comparator
Queue<Customer> cpq = new PriorityQueue<>(7, idComp);
addToQueue(cpq);
pollFromQueue(cpq);
}
public static Comparator<Customer> idComp = new Comparator<Customer>(){
@Override
public int compare(Customer o1, Customer o2) {
return (int) (o1.getId() - o2.getId());
}
};
//utility method to add random data to Queue
private static void addToQueue(Queue<Customer> cq){
Random rand = new Random();
for(int i=0;i<7;i++){
int id = rand.nextInt(100);
cq.add(new Customer(id, "KV"+id));
}
}
private static void pollFromQueue(Queue<Customer> cq){
while(true){
Customer c = cq.poll();
if(c == null) break;
System.out.println("Customer Polled : "+c.getId() + " "+ c.getName());
}
}
}