JavaRush /جاوا بلاگ /Random-UR /جاوا میں موازنہ کرنے والا

جاوا میں موازنہ کرنے والا

گروپ میں شائع ہوا۔
ہیلو! آج ہم اشیاء کا موازنہ کرنے کے بارے میں بات کریں گے۔ ہمم... لیکن ایسا لگتا ہے کہ ہم پہلے ہی اس کے بارے میں ایک سے زیادہ بار بات کر چکے ہیں؟ :/ ہم جانتے ہیں کہ " ==" آپریٹر کیسے کام کرتا ہے، ساتھ ہی equals()اور طریقے hashCode()۔ موازنہ واقعی اس کے بارے میں نہیں ہے۔ پہلے، ہمارا مطلب "مساوات کے لیے اشیاء کی جانچ" کی طرح تھا۔ جاوا میں موازنہ کرنے والا - 1لیکن اشیاء کا ایک دوسرے سے موازنہ کرنے کے مقاصد بالکل مختلف ہو سکتے ہیں! سب سے واضح چھانٹنا ہے۔ 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 = "Даша";

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

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

[Даша, Маша, Саша]
اگر آپ کو کلاس 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;
   }

   //...геттеры, сеттеры, 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۔ اور، بالکل فطری طور پر، جاوا کو یہ بھی نہیں معلوم! جب ہم Collections.sort()اشیاء کی فہرست کو کسی طریقہ میں منتقل کرنے کی کوشش کرتے ہیں 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(20012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

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

       //ошибка компилятора!
       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;
   }

   //...геттеры, сеттеры, toString()

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

       //тут раньше была ошибка
       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()۔ اس کے بجائے، ہم اپنے پروگرام میں ایک الگ کمپیریٹر کلاس بنا سکتے ہیں اور اسے اپنی ضرورت کی چھانٹی کرنا سکھا سکتے ہیں!
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()- یہ ایک انٹرفیس طریقہ ہے Comparator، جسے لاگو کرنا ضروری ہے۔ یہ دو اشیاء کو بطور ان پٹ لیتا ہے 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()میں بیان کردہ قدرتی چھانٹی کا استعمال نہیں کرے گا ۔ اس کے بجائے، یہ اس کو بھیجے گئے موازنہ کنندہ سے ترتیب دینے والے الگورتھم کو لاگو کرے گا۔ یہ ہمیں کیا فوائد دیتا ہے؟ سب سے پہلے، تحریری کوڈ کے ساتھ مطابقت. ہم نے موجودہ طریقہ کو برقرار رکھتے ہوئے چھانٹنے کا ایک نیا، مخصوص طریقہ بنایا ہے، جسے زیادہ تر معاملات میں استعمال کیا جائے گا۔ ہم نے کلاس کو بالکل ہاتھ نہیں لگایا ۔ وہ جیسا تھا ویسا ہی رہا: compareTo()CarCarComparable
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();
   }

   //...геттеры, сеттеры, toString()

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