CodeGym /جاوا بلاگ /Random-UR /جاوا میں String اور Equals موازنہ کا موازنہ کریں۔
John Squirrels
سطح
San Francisco

جاوا میں String اور Equals موازنہ کا موازنہ کریں۔

گروپ میں شائع ہوا۔
ہائے! آج ہم ایک بہت اہم اور دلچسپ موضوع کے بارے میں بات کریں گے، یعنی اشیاء کے ساتھ اشیاء کا موازنہ ( Compare Strings and Equals)۔ تو جاوا میں، اعتراض A اعتراض B کے برابر کب ہوگا ؟ آئیے ایک مثال لکھنے کی کوشش کریں:

public class Car {

   String model;
   int maxSpeed;

   public static void main(String[] args) {
      
       Car car1 = new Car();
       car1.model = "Ferrari";
       car1.maxSpeed = 300;

       Car car2 = new Car();
       car2.model = "Ferrari";
       car2.maxSpeed = 300;

       System.out.println(car1 == car2);
   }
}
کنسول آؤٹ پٹ: غلط انتظار کرو، روکو۔ یہ دونوں کاریں برابر کیوں نہیں ہیں؟ ہم نے انہیں وہی خصوصیات تفویض کیں، لیکن موازنہ کا نتیجہ غلط ہے۔ جواب بہت سادہ ہے۔ == آپریٹر آبجیکٹ کے حوالہ جات کا موازنہ کرتا ہے، آبجیکٹ کی خصوصیات کا نہیں۔ دو اشیاء میں ایک جیسی اقدار کے ساتھ 500 فیلڈز بھی ہو سکتے ہیں، لیکن ان کا موازنہ کرنا پھر بھی غلط نکلے گا۔ آخر کار، car1 اور car2 حوالہ جات دو مختلف اشیاء، یعنی دو مختلف پتوں کی طرف اشارہ کرتے ہیں۔ ایک ایسی صورتحال کا تصور کریں جہاں آپ لوگوں کا موازنہ کر رہے ہوں۔ یقیناً، دنیا میں کہیں کوئی ایسا شخص ہے جو آپ کا ایک جیسا نام، آنکھوں کا رنگ، عمر، قد، بالوں کا رنگ وغیرہ شیئر کرتا ہے۔ جو آپ کو بہت سے معاملات میں ایک جیسا بناتا ہے، لیکن آپ پھر بھی جڑواں نہیں ہیں — اور ظاہر ہے کہ آپ نہیں ہیں۔ ایک ہی شخص.
مساوی اور تار کا موازنہ - 2
== آپریٹر تقریباً یہی منطق استعمال کرتا ہے جب ہم اسے دو اشیاء کا موازنہ کرنے کے لیے استعمال کرتے ہیں ۔ لیکن اگر آپ کو مختلف منطق استعمال کرنے کے لیے اپنے پروگرام کی ضرورت ہو تو کیا ہوگا؟ مثال کے طور پر، فرض کریں کہ آپ کا پروگرام DNA تجزیہ کرتا ہے۔ یہ دو افراد کے جینیاتی کوڈ کا موازنہ کرتا ہے، اور اس بات کا تعین کرتا ہے کہ آیا وہ جڑواں ہیں۔

public class Man {

   int geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = 1111222233;

       Man man2 = new Man();
       man2.geneticCode = 1111222233;

       System.out.println(man1 == man2);
   }
}
کنسول آؤٹ پٹ: غلط ہمیں ایک ہی منطقی نتیجہ ملتا ہے (کیونکہ ہم نے زیادہ تبدیلی نہیں کی)، لیکن اب وہ منطق اچھی نہیں ہے! آخر کار، حقیقی زندگی میں، ڈی این اے کے تجزیے سے ہمیں 100% ضمانت ملنی چاہیے کہ ہمارے سامنے جڑواں بچے کھڑے ہیں۔ لیکن ہمارا پروگرام اور == آپریٹر ہمیں اس کے برعکس بتاتے ہیں۔ ہم اس رویے کو کیسے تبدیل کرتے ہیں اور اس بات کو یقینی بناتے ہیں کہ پروگرام درست نتیجہ نکالتا ہے جب ڈی این اے میچ کرتا ہے؟ جاوا کے پاس اس کے لیے ایک خاص طریقہ ہے: equals() ۔ toString() طریقہ کی طرح ، جس پر ہم نے پہلے بات کی ہے، equals() کا تعلق آبجیکٹ کلاس سے ہے - جاوا میں سب سے اہم کلاس، وہ کلاس جس سے دیگر تمام کلاسز اخذ کرتے ہیں۔ لیکن equals() ہمارے پروگرام کے رویے کو خود سے تبدیل نہیں کرتا ہے۔

public class Man {

   String geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = "111122223333";

       Man man2 = new Man();
       man2.geneticCode = "111122223333";

       System.out.println(man1.equals(man2));
   }
}
کنسول آؤٹ پٹ: غلط بالکل وہی نتیجہ، تو ہمیں اس طریقہ کی کیا ضرورت ہے؟ :/ یہ سب آسان ہے۔ یہاں مسئلہ یہ ہے کہ ہم فی الحال یہ طریقہ استعمال کر رہے ہیں کیونکہ یہ آبجیکٹ کلاس میں لاگو ہوتا ہے۔ اور اگر ہم آبجیکٹ کلاس کے کوڈ میں جائیں اور طریقہ کار کے نفاذ کو دیکھیں تو ہم یہ دیکھیں گے:

public boolean equals(Object obj) {
   return (this == obj);
}
یہی وجہ ہے کہ پروگرام کے رویے میں کوئی تبدیلی نہیں آئی! بالکل وہی == آپریٹر (جو حوالہ جات کا موازنہ کرتا ہے) آبجیکٹ کلاس کے برابر () طریقہ کے اندر استعمال ہوتا ہے۔ لیکن اس طریقہ کے ساتھ چال یہ ہے کہ ہم اسے اوور رائڈ کر سکتے ہیں۔ اوور رائڈ کرنے کا مطلب ہماری مین کلاس میں اپنا اپنا مساوی () طریقہ لکھنا ہے ، اسے وہ طرز عمل دینا ہے جس کی ہمیں ضرورت ہے! فی الحال، ہمیں یہ حقیقت پسند نہیں ہے کہ man1.equals(man2) بنیادی طور پر man1 == man2 کے برابر ہے ۔ اس صورت حال میں ہم کیا کریں گے یہ ہے:

public class Man { 

   int dnaCode; 

   public boolean equals(Man man) { 
       return this.dnaCode ==  man.dnaCode; 

   } 

   public static void main(String[] args) { 

       Man man1 = new Man(); 
       man1.dnaCode = 1111222233; 

       Man man2 = new Man(); 
       man2.dnaCode = 1111222233; 

       System.out.println(man1.equals(man2)); 

   } 
} 
کنسول آؤٹ پٹ: true اب ہمیں ایک بالکل مختلف نتیجہ ملتا ہے! اپنا اپنا مساوی () طریقہ لکھ کر اور اسے معیاری کی بجائے استعمال کرتے ہوئے، ہم نے درست طرز عمل پیدا کیا ہے: اب اگر دو لوگوں کا ڈی این اے ایک ہی ہے، تو پروگرام کی رپورٹ "ڈی این اے کے تجزیے سے ثابت ہو گیا ہے کہ وہ جڑواں ہیں" اور درست ہو جاتا ہے! اپنی کلاسوں میں equals() طریقہ کو اوور رائیڈ کر کے ، آپ آسانی سے جو بھی آبجیکٹ کمپیریزن منطق آپ کو درکار ہو بنا سکتے ہیں۔ درحقیقت، ہم نے صرف آبجیکٹ کے موازنہ پر توجہ دی ہے۔ ہمارے سامنے، اس موضوع پر اب بھی ایک بڑا اسٹینڈ لون سبق باقی ہے (اگر آپ دلچسپی رکھتے ہیں تو اب اس پر غور کریں)۔

جاوا میں تاروں کا موازنہ کرنا

ہم ہر چیز سے الگ الگ سٹرنگ موازنہ پر کیوں غور کر رہے ہیں؟ حقیقت یہ ہے کہ سٹرنگز پروگرامنگ میں اپنے طور پر ایک موضوع ہیں۔ سب سے پہلے، اگر آپ جاوا کے تمام پروگراموں کو لے لیں جو اب تک لکھے گئے ہیں، آپ کو معلوم ہوگا کہ ان میں تقریباً 25% اشیاء تاریں ہیں۔ اس لیے یہ موضوع بہت اہم ہے۔ دوسرا، تاروں کا موازنہ کرنے کا عمل واقعی دیگر اشیاء سے بہت مختلف ہے۔ ایک سادہ مثال پر غور کریں:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
کنسول آؤٹ پٹ: غلط لیکن ہم غلط کیوں ہوئے؟ بہر حال، تار بالکل ایک جیسے ہیں، لفظ کے بدلے :/ آپ نے اس کی وجہ کا اندازہ لگایا ہوگا: اس کی وجہ یہ ہے کہ == آپریٹر حوالہ جات کا موازنہ کرتا ہے ! واضح طور پر، s1 اور s2 میموری میں مختلف پتے ہیں۔ اگر آپ نے اس کے بارے میں سوچا، تو آئیے اپنی مثال پر دوبارہ کام کریں:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       System.out.println(s1 == s2);
   }
}
اب ہمارے پاس ایک بار پھر دو حوالہ جات ہیں، لیکن نتیجہ اس کے بالکل برعکس ہے: کنسول آؤٹ پٹ: سچ بے بسی سے کنفیوزڈ؟ آئیے معلوم کریں کہ کیا ہو رہا ہے۔ == آپریٹر واقعی میموری ایڈریس کا موازنہ کرتا ہے ۔ یہ ہمیشہ سچ ہے اور آپ کو اس پر شک کرنے کی ضرورت نہیں ہے۔ اس کا مطلب ہے کہ اگر s1 == s2 صحیح لوٹتا ہے، تو ان دونوں تاروں کا پتہ ایک ہی ہے۔ اور واقعی یہ سچ ہے! اب وقت آگیا ہے کہ آپ کو تاروں کو ذخیرہ کرنے کے لیے میموری کے ایک خاص شعبے سے متعارف کرایا جائے: سٹرنگ پول
مساوی اور تار کا موازنہ - 3
سٹرنگ پول ان تمام سٹرنگ ویلیوز کو ذخیرہ کرنے کا ایک علاقہ ہے جو آپ اپنے پروگرام میں بناتے ہیں۔ اسے کیوں بنایا گیا؟ جیسا کہ ہم نے پہلے کہا، تاریں تمام اشیاء کی ایک بڑی فیصد کی نمائندگی کرتی ہیں۔ کوئی بھی بڑا پروگرام بہت ساری تاریں بناتا ہے۔ سٹرنگ پول میموری کو بچانے کے لیے بنایا گیا تھا: سٹرنگز وہاں رکھی جاتی ہیں اور پھر بعد میں بنائی گئی تاریں میموری کے اسی علاقے کا حوالہ دیتی ہیں — ہر بار اضافی میموری مختص کرنے کی ضرورت نہیں ہوتی ہے۔ ہر بار جب آپ String = "........" لکھتے ہیں تو پروگرام چیک کرتا ہے کہ آیا سٹرنگ پول میں ایک جیسی سٹرنگ موجود ہے۔ اگر وہاں ہے، تو ایک نئی تار نہیں بنائی جائے گی۔ اور نیا حوالہ سٹرنگ پول میں اسی ایڈریس کی طرف اشارہ کرے گا (جہاں ایک جیسی سٹرنگ واقع ہے)۔ تو جب ہم نے لکھا
String s1 = "CodeGym is the best website for learning Java!";
String s2 = "CodeGym is the best website for learning Java!";
s2 اسی جگہ کی طرف اشارہ کرتا ہے جیسے s1 ۔ پہلا بیان سٹرنگ پول میں ایک نئی سٹرنگ بناتا ہے۔ دوسرا بیان صرف میموری کے اسی علاقے کی طرف اشارہ کرتا ہے s1 ۔ آپ مزید 500 ایک جیسی تاریں بنا سکتے ہیں اور نتیجہ تبدیل نہیں ہوگا۔ ذرا رکو. اگر یہ سچ ہے تو یہ مثال پہلے کیوں کام نہیں کرتی تھی؟

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
مجھے لگتا ہے کہ آپ کی وجدان نے پہلے ہی آپ کو وجہ بتا دی ہے =) مزید پڑھنے سے پہلے اندازہ لگانے کی کوشش کریں۔ آپ دیکھ سکتے ہیں کہ ان دو تاروں کا اعلان مختلف طریقوں سے کیا گیا تھا۔ ایک نئے آپریٹر کے ساتھ، اور دوسرا اس کے بغیر۔ اس کی وجہ یہاں ہے۔ جب نیا آپریٹر کسی شے کو بنانے کے لیے استعمال کیا جاتا ہے، تو یہ زبردستی آبجیکٹ کے لیے میموری کا ایک نیا علاقہ مختص کرتا ہے۔ اور نئے کا استعمال کرتے ہوئے بنائی گئی سٹرنگ سٹرنگ پول میں ختم نہیں ہوتی — یہ ایک الگ آبجیکٹ بن جاتی ہے، چاہے اس کا متن سٹرنگ پول میں کسی سٹرنگ سے بالکل مماثل ہو۔ یعنی، اگر ہم درج ذیل کوڈ لکھیں:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       String s3 = new String("CodeGym is the best website for learning Java!");
   }
}
میموری میں، یہ اس طرح لگتا ہے:
مساوی اور تار کا موازنہ - 4
اور جب بھی آپ new استعمال کرتے ہوئے کوئی نیا آبجیکٹ بناتے ہیں، میموری کا ایک نیا علاقہ مختص کیا جاتا ہے، چاہے نئی سٹرنگ کے اندر کا متن ایک جیسا ہی ہو! ایسا لگتا ہے کہ ہم نے == آپریٹر کا پتہ لگا لیا ہے۔ لیکن ہمارے نئے جاننے والے، برابر () طریقہ کا کیا ہوگا؟

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1.equals(s2));
   }
}
کنسول آؤٹ پٹ: سچی دلچسپ۔ ہمیں یقین ہے کہ s1 اور s2 میموری میں مختلف علاقوں کی طرف اشارہ کرتے ہیں۔ لیکن equals() طریقہ اب بھی ہمیں بتاتا ہے کہ وہ برابر ہیں۔ کیوں؟ یاد رکھیں ہم نے پہلے کہا تھا کہ اشیاء کا موازنہ کرنے کے لیے equals() طریقہ کو اوور رائیڈ کیا جا سکتا ہے تاہم ہم چاہتے ہیں؟ بس وہی ہے جو انہوں نے سٹرنگ کلاس کے ساتھ کیا ہے۔ یہ equals() طریقہ کو اوور رائیڈ کرتا ہے۔ اور حوالہ جات کا موازنہ کرنے کے بجائے، یہ تاروں میں حروف کی ترتیب کا موازنہ کرتا ہے۔ اگر متن یکساں ہے، تو اس سے کوئی فرق نہیں پڑتا کہ وہ کیسے بنائے گئے یا کہاں محفوظ کیے گئے: چاہے سٹرنگ پول میں ہو یا میموری کے الگ حصے میں۔ موازنہ کا نتیجہ درست نکلے گا۔ ویسے، جاوا آپ کو کیس غیر حساس سٹرنگ موازنہ کرنے دیتا ہے۔ عام طور پر، اگر کسی ایک تار میں تمام بڑے حروف ہوں، تو موازنہ کا نتیجہ غلط ہوگا:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CODEGYM IS THE BEST WEBSITE FOR LEARNING JAVA!");
       System.out.println(s1.equals(s2));
   }
}
کنسول آؤٹ پٹ: غلط کیس غیر حساس موازنہ کے لیے، String کلاس میں equalsIgnoreCase() طریقہ ہے۔ آپ اسے استعمال کر سکتے ہیں اگر آپ صرف لیٹر کیس کی بجائے مخصوص حروف کی ترتیب کا موازنہ کرنے کی فکر کرتے ہیں۔ مثال کے طور پر، دو پتوں کا موازنہ کرتے وقت یہ مددگار ثابت ہو سکتا ہے:

public class Main {

   public static void main(String[] args) {

       String address1 = "2311 Broadway Street, San Francisco";
       String address2 = new String("2311 BROADWAY STREET, SAN FRANCISCO");
       System.out.println(address1.equalsIgnoreCase(address2));
   }
}
اس معاملے میں، ہم واضح طور پر ایک ہی ایڈریس کے بارے میں بات کر رہے ہیں، لہذا یہ سمجھ میں آتا ہے کہ equalsIgnoreCase() طریقہ استعمال کریں۔

String.intern() طریقہ

String کلاس کا ایک اور مشکل طریقہ ہے: intern() ; انٹرن () طریقہ سٹرنگ پول کے ساتھ براہ راست کام کرتا ہے۔ اگر آپ انٹرن() طریقہ کو کسی تار پر کال کرتے ہیں:
  • یہ چیک کرتا ہے کہ آیا سٹرنگ پول میں کوئی مماثل سٹرنگ ہے۔
  • اگر وہاں ہے تو، یہ پول میں سٹرنگ کا حوالہ لوٹاتا ہے۔
  • اگر نہیں، تو یہ سٹرنگ پول میں سٹرنگ جوڑتا ہے اور اس کا حوالہ واپس کرتا ہے۔
new استعمال کرتے ہوئے حاصل کردہ سٹرنگ ریفرنس پر intern() طریقہ استعمال کرنے کے بعد ، ہم == آپریٹر کا استعمال اسٹرنگ پول سے سٹرنگ حوالہ سے موازنہ کرنے کے لیے کر سکتے ہیں۔

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2.intern());
   }
}
کنسول آؤٹ پٹ: true جب ہم نے پہلے ان تاروں کا موازنہ intern() کے بغیر کیا تو نتیجہ غلط نکلا۔ اب انٹرن() طریقہ چیک کرتا ہے کہ آیا سٹرنگ "CodeGym جاوا سیکھنے کے لیے بہترین سائٹ ہے!" سٹرنگ پول میں ہے. بالکل، یہ ہے: ہم نے اسے بنایا ہے۔

String s1 = "CodeGym is the best website for learning Java!";
ہم چیک کرتے ہیں کہ آیا s1 اور s2.intern() کے ذریعہ واپس کردہ حوالہ میموری کے ایک ہی حصے کی طرف اشارہ کرتا ہے۔ اور یقیناً، وہ کرتے ہیں :) خلاصہ یہ ہے کہ اس اہم اصول کو یاد رکھیں اور لاگو کریں: تاروں کا موازنہ کرنے کے لیے ہمیشہ برابر () طریقہ استعمال کریں! تاروں کا موازنہ کرتے وقت، ہمارا مطلب تقریباً ہمیشہ حوالہ جات، میموری کے علاقوں یا کسی اور چیز کے بجائے ان کے کرداروں کا موازنہ کرنا ہوتا ہے۔ equals () طریقہ بالکل وہی کرتا ہے جس کی آپ کو ضرورت ہے۔ جو کچھ آپ نے سیکھا ہے اس کو تقویت دینے کے لیے، ہم تجویز کرتے ہیں کہ آپ ہمارے جاوا کورس سے ایک ویڈیو سبق دیکھیں
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION