CodeGym /جاوا بلاگ /Random-UR /جاوا کی کمپیریٹر کلاس
John Squirrels
سطح
San Francisco

جاوا کی کمپیریٹر کلاس

گروپ میں شائع ہوا۔
ہائے! آج ہم اشیاء کا موازنہ کرنے کے بارے میں بات کرنے جا رہے ہیں۔ جاوا کی کمپیریٹر کلاس - 1 ہمم... لیکن کیا ہم پہلے ہی اس موضوع پر ایک سے زیادہ بار بات نہیں کر چکے ہیں؟ :/ ہم جانتے ہیں کہ ==آپریٹر کیسے کام کرتا ہے، ساتھ ہی equals()اور hashCode()طریقے بھی۔ موازنہ تھوڑا مختلف ہے۔ اس سے پہلے، ہمارا غالباً مطلب تھا "مساوات کے لیے اشیاء کی جانچ کرنا"۔ لیکن اشیاء کا ایک دوسرے سے موازنہ کرنے کی وجوہات بالکل مختلف ہو سکتی ہیں! ان میں سب سے واضح چھانٹنا ہے۔ میرے خیال میں اگر آپ کو نمبروں یا تاروں کو ترتیب دینے کے لیے کہا جائے ArrayList<>تو آپ اسے بغیر کسی پریشانی کے سنبھال سکیں گے:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       String name1 = "Masha";
       String name2 = "Sasha";
       String name3 = "Dasha";

       List<String> names = new ArrayList<>();
       names.add(name1);
       names.add(name2);
       names.add(name3);

       Collections.sort(names);
       System.out.println(names);
   }
}
کنسول آؤٹ پٹ:

[Dasha, Masha, Sasha]
اگر آپ کو Collectionsکلاس اور اس کا sort()طریقہ یاد ہے تو شاباش! مجھے لگتا ہے کہ آپ کو بھی نمبروں کے ساتھ کوئی پریشانی نہیں ہوگی۔ یہاں آپ کے لیے ایک زیادہ مشکل کام ہے:
public class Car {

   private int manufactureYear;
   private String model;
   private int maxSpeed;

   public Car(int manufactureYear, String model, int maxSpeed) {
       this.manufactureYear = manufactureYear;
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   // ...getters, setters, toString()

}

import java.util.ArrayList;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);
   }
}
کام دراصل آسان ہے۔ ہمارے پاس ایک Carکلاس اور 3 کار آبجیکٹ ہیں۔ کیا آپ برائے مہربانی فہرست میں کاروں کو ترتیب دیں گے؟ آپ شاید پوچھیں گے، "انہیں کیسے ترتیب دیا جائے؟" نام کے ساتھ؟ تیاری کے سال کی طرف سے؟ زیادہ سے زیادہ رفتار سے؟ بہترین سوال۔ اس وقت، ہم نہیں جانتے کہ Carاشیاء کو کیسے ترتیب دیا جائے۔ اور، بالکل فطری طور پر، جاوا کو یہ بھی نہیں معلوم! جب ہم اشیاء کی فہرست کو طریقہ Carمیں منتقل کرنے کی کوشش کرتے ہیں Collections.sort()، تو ہمیں ایک خرابی ملتی ہے:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(20012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);

       // Compilation error!
       Collections.sort(cars);
   }
}
اور درحقیقت، زبان کو یہ کیسے معلوم ہوگا کہ آپ کی لکھی ہوئی کلاسوں کی اشیاء کو کیسے ترتیب دیا جائے؟ یہ اس بات پر منحصر ہے کہ آپ کے پروگرام کو کیا کرنے کی ضرورت ہے۔ ہمیں کسی نہ کسی طرح جاوا کو ان اشیاء کا موازنہ کرنا سکھانا چاہیے۔ اور ان کا موازنہ کرنا جس طرح ہم چاہتے ہیں۔ جاوا کے پاس اس کے لیے ایک خاص طریقہ کار ہے: Comparableانٹرفیس۔ کسی نہ کسی طرح ہماری اشیاء کا موازنہ اور ترتیب دینے کے لیے Car، کلاس کو اس انٹرفیس کو نافذ کرنا چاہیے، جو کہ ایک طریقہ پر مشتمل ہے: compareTo():
public class Car implements Comparable<Car> {

   private int manufactureYear;
   private String model;
   private int maxSpeed;

   public Car(int manufactureYear, String model, int maxSpeed) {
       this.manufactureYear = manufactureYear;
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   @Override
   public int compareTo(Car o) {
       return 0;
   }

   // ...getters, setters, toString()

}
براہ مہربانی نوٹ کریںکہ ہم نے Comparable<Car>انٹرفیس کی وضاحت کی، نہ صرف Comparable۔ یہ ایک پیرامیٹرائزڈ انٹرفیس ہے، یعنی ہمیں مخصوص متعلقہ کلاس کی وضاحت کرنی چاہیے۔ اصولی طور پر، آپ <Car>انٹرفیس سے ہٹا سکتے ہیں، لیکن پھر موازنہ Objectڈیفالٹ کے ذریعہ اشیاء پر مبنی ہوگا۔ طریقہ کے بجائے compareTo(Car o)، ہماری کلاس میں یہ ہوگا:
@Override
   public int compareTo(Object o) {
       return 0;
   }
یقیناً، ہمارے لیے اس کے ساتھ کام کرنا بہت آسان ہے Car۔ طریقہ کار کے اندر compareTo()، ہم کاروں کا موازنہ کرنے کے لیے اپنی منطق کو نافذ کرتے ہیں۔ فرض کریں کہ ہمیں انہیں تیاری کے سال کے لحاظ سے ترتیب دینے کی ضرورت ہے۔ آپ نے شاید محسوس کیا ہے کہ compareTo()طریقہ ایک واپس کرتا ہے int، a نہیں boolean۔ یہ آپ کو حیران نہ ہونے دیں۔ جب ہم دو اشیاء کا موازنہ کرتے ہیں تو 3 امکانات ہوتے ہیں:
  • а < b
  • a > b
  • a == b.
booleanاس کی صرف 2 اقدار ہیں: صحیح اور غلط، جو اشیاء کا موازنہ کرنے کے لیے اچھی طرح سے کام نہیں کرتی ہیں۔ کے ساتھ int، سب کچھ بہت آسان ہے۔ اگر واپسی کی قیمت ہے > 0تو a > b. اگر کا نتیجہ compareToہے < 0، تو a < b۔ اور، اگر نتیجہ ہے == 0، تو دو اشیاء برابر ہیں: a == b۔ تیاری کے سال کے لحاظ سے کاروں کو ترتیب دینا ہماری کلاس کو سکھانا آسان ہے:
@Override
public int compareTo(Car o) {
   return this.getManufactureYear() - o.getManufactureYear();
}
لیکن یہاں کیا ہو رہا ہے؟ ہم ایک کار آبجیکٹ ( this) لیتے ہیں، اس کار کی تیاری کا سال حاصل کرتے ہیں، اور اس سے دوسری کار کی تیاری کا سال گھٹاتے ہیں (جس کے ساتھ آبجیکٹ کا موازنہ کیا جا رہا ہے)۔ اگر پہلی کار کی تیاری کا سال زیادہ ہے، تو طریقہ واپس آئے گا int > 0۔ اس کا مطلب ہے کہ this car >گاڑی o۔ اس کے برعکس، اگر دوسری کار کی تیاری کا سال ( о) زیادہ ہے، تو طریقہ ایک منفی نمبر لوٹائے گا، جس کا مطلب ہے کہ o > this۔ آخر میں، اگر وہ برابر ہیں، تو طریقہ واپس آ جائے گا 0. یہ سادہ طریقہ کار ہمارے لیے Carاشیاء کے مجموعوں کو ترتیب دینے کے لیے پہلے ہی کافی ہے! آپ کو اور کچھ کرنے کی ضرورت نہیں ہے۔ اس کی جانچ پڑتال کر:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);

       // There was previously an error here
       Collections.sort(cars);
       System.out.println(cars);
   }
}
کنسول آؤٹ پٹ:

[Car{manufactureYear=1990, model='Ferrari 360 Spider', maxSpeed=310}, 
Car{manufactureYear=2010, model='Bugatti Veyron', maxSpeed=350}, 
Car{manufactureYear=2012, model='Lamborghini Gallardo', maxSpeed=290}]
کاروں کو ترتیب دیا گیا ہے جیسا کہ ہم چاہتے ہیں! :) جاوا کی کمپیریٹر کلاس - 2میں کب استعمال کروں Comparable؟ مقابلے کے طریقہ کار کو Comparableقدرتی ترتیب کہا جاتا ہے۔ اس کی وجہ یہ ہے کہ طریقہ کار میں compareTo()آپ اس کلاس کی اشیاء کا موازنہ کرنے کا سب سے عام، یا قدرتی طریقہ بیان کرتے ہیں۔ جاوا میں پہلے سے ہی قدرتی ترتیب ہے۔ مثال کے طور پر، جاوا جانتا ہے کہ تاروں کو اکثر حروف تہجی کے حساب سے ترتیب دیا جاتا ہے، اور اعداد کو عددی قدر میں اضافہ کر کے۔ لہذا، اگر آپ sort()نمبروں یا تاروں کی فہرست میں طریقہ کو کال کرتے ہیں، تو وہ ترتیب دی جائیں گی۔ Comparable<Car>اگر ہمارا پروگرام عام طور پر تیاری کے سال کے لحاظ سے کاروں کا موازنہ اور ترتیب دیتا ہے، تو ہمیں انٹرفیس اور compareTo()طریقہ کار کا استعمال کرتے ہوئے کاروں کے لیے قدرتی چھانٹی کی وضاحت کرنی چاہیے ۔ لیکن اگر یہ ہمارے لیے کافی نہیں ہے تو کیا ہوگا؟ آئیے تصور کریں کہ ہمارا پروگرام اتنا آسان نہیں ہے۔ زیادہ تر معاملات میں، کاروں کی قدرتی چھانٹی (جسے ہم نے تیاری کے سال کے لحاظ سے انجام دیا ہے) ہمارے لیے موزوں ہے۔ لیکن بعض اوقات ہمارے صارفین تیز رفتار ڈرائیونگ کے شوقین ہوتے ہیں۔ اگر ہم ان کے استعمال کے لیے کار کیٹلاگ تیار کر رہے ہیں، تو کاروں کو زیادہ سے زیادہ رفتار کے مطابق ترتیب دیا جانا چاہیے۔ جاوا کی کمپیریٹر کلاس - 3مثال کے طور پر، فرض کریں کہ ہمیں 15٪ وقت کی طرح ترتیب دینے کی ضرورت ہے۔ Carہمارے لیے یہ واضح طور پر کافی نہیں ہے کہ ہم کلاس کی قدرتی ترتیب کو تیاری کے سال کے بجائے رفتار کے مطابق ترتیب دیں ۔ لیکن ہم اپنے 15% صارفین کو نظر انداز نہیں کر سکتے۔ تو ہم کیا کریں؟ ایک اور انٹرفیس یہاں ہماری مدد کے لیے آتا ہے: Comparator. بالکل اسی طرح Comparable، یہ ایک پیرامیٹرائزڈ انٹرفیس ہے۔ کیا فرق ہے؟ Comparableہماری اشیاء کو "مقابلہ" بناتا ہے اور ان کی سب سے قدرتی ترتیب ترتیب کی وضاحت کرتا ہے، یعنی وہ ترتیب جو زیادہ تر معاملات میں استعمال کیا جائے گا۔ Comparatorایک الگ "موازنہ" انٹرفیس ہے۔ اگر ہمیں کسی قسم کے خصوصی ترتیب دینے کی ضرورت ہے، تو ہمیں Carکلاس میں جانے اور کی منطق کو تبدیل کرنے کی ضرورت نہیں ہے compareTo()۔ اس کے بجائے، ہم ایک الگ کلاس بنا سکتے ہیں جو Comparator کو لاگو کرتی ہے اور اسے سکھا سکتی ہے کہ ہمیں جس ترتیب کی ضرورت ہے اسے کیسے انجام دیا جائے!
import java.util.Comparator;

public class MaxSpeedCarComparator implements Comparator<Car> {

   @Override
   public int compare(Car o1, Car o2) {
       return o1.getMaxSpeed() - o2.getMaxSpeed();
   }
}
جیسا کہ آپ دیکھ سکتے ہیں، ہماری بات Comparatorبہت آسان ہے۔ ہمیں صرف ایک انٹرفیس طریقہ کو لاگو کرنے کی ضرورت ہے: compare(). یہ دو Carاشیاء کو ان پٹ کے طور پر لیتا ہے اور ان کی زیادہ سے زیادہ رفتار کا معمول کے انداز میں موازنہ کرتا ہے (تخفیف کے ذریعے)۔ جیسے compareTo()، یہ ایک لوٹاتا ہے int، اور موازنہ کا اصول ایک جیسا ہے۔ ہم اسے کیسے استعمال کرتے ہیں؟ یہ سب سیدھا ہے:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);

       Comparator speedComparator = new MaxSpeedCarComparator();
       Collections.sort(cars, speedComparator);

       System.out.println(cars);
   }
}
کنسول آؤٹ پٹ:

[Car{manufactureYear=2012, model='Lamborghini Gallardo', maxSpeed=290}, 
Car{manufactureYear=1990, model='Ferrari 360 Spider', maxSpeed=310}, 
Car{manufactureYear=2010, model='Bugatti Veyron', maxSpeed=350}]
ہم صرف ایک کمپیریٹر آبجیکٹ بناتے ہیں اور اسے Collections.sort()ترتیب دینے والی فہرست کے ساتھ طریقہ کار میں بھیج دیتے ہیں۔ جب طریقہ ایک موازنہ حاصل کرتا ہے، تو یہ کلاس کے طریقہ کار sort()میں بیان کردہ قدرتی ترتیب کو استعمال نہیں کرتا ہے ۔ اس کے بجائے، یہ اس کو بھیجے گئے موازنہ کنندہ کے ذریعہ بیان کردہ ترتیب دینے والے الگورتھم کو لاگو کرتا ہے۔ ایسا کرنے کے کیا فائدے ہیں؟ پہلے، موجودہ کوڈ کے ساتھ مطابقت۔ ہم نے ایک نیا، خصوصی چھانٹنے کا طریقہ بنایا ہے، موجودہ طریقہ کو برقرار رکھتے ہوئے جسے زیادہ تر وقت استعمال کیا جائے گا۔ ہم نے کلاس کو بالکل ہاتھ نہیں لگایا ۔ یہ ایک تھا ، اور اسی طرح یہ باقی ہے: CarcompareTo()CarComparable
public class Car implements Comparable<Car> {

   private int manufactureYear;
   private String model;
   private int maxSpeed;

   public Car(int manufactureYear, String model, int maxSpeed) {
       this.manufactureYear = manufactureYear;
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   @Override
   public int compareTo(Car o) {
       return this.getManufactureYear() - o.getManufactureYear();
   }

   // ...getters, setters, toString()

}
دوسرا، لچک. ہم جتنے چاہیں ترتیب دینے والے الگورتھم شامل کر سکتے ہیں۔ مثال کے طور پر، ہم کاروں کو رنگ، رفتار، وزن، یا بیٹ مین فلموں میں کار کو کتنی بار استعمال کیا گیا ہے کے لحاظ سے ترتیب دے سکتے ہیں۔ ہمیں صرف ایک اضافی تخلیق کرنے کی ضرورت ہے Comparator۔ یہی ہے! آج آپ نے دو انتہائی اہم میکانزم کا مطالعہ کیا ہے جنہیں آپ اکثر کام پر حقیقی منصوبوں میں استعمال کریں گے۔ لیکن، جیسا کہ آپ جانتے ہیں، پریکٹس کے بغیر تھیوری کچھ بھی نہیں ہے۔ اب وقت آگیا ہے کہ آپ اپنے علم کو مضبوط کریں اور کچھ کام مکمل کریں!
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION