JavaRush /Java blogi /Random-UZ /Java va String solishtirishda tenglar - String taqqoslash...

Java va String solishtirishda tenglar - String taqqoslash

Guruhda nashr etilgan
Salom! Bugun biz juda muhim va qiziqarli mavzu haqida gaplashamiz, ya'ni Java'da ob'ektlarni bir-biri bilan teng () bilan solishtirish. Haqiqatan ham, Java-da qanday hollarda A ob'ekti B ob'ektiga teng bo'ladi ? Tenglar va qatorlarni taqqoslash - 1Keling, misol yozishga harakat qilaylik:
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);
   }
}
Konsol chiqishi:

false
Mayli, to'xtang. Nima uchun, aslida, bu ikki mashina teng emas? Biz ularga bir xil xususiyatlarni berdik, ammo taqqoslash natijasi noto'g'ri. Javob oddiy. Operator ==ob'ektlarning xususiyatlarini emas, balki havolalarni taqqoslaydi. Agar ikkita ob'ekt 500 ta bir xil xususiyatga ega bo'lsa ham, taqqoslash natijasi noto'g'ri bo'ladi. Axir, havolalar ikki xil ob'ektga , ikki xil manzilga car1ishora qiladi . Odamlarni taqqoslash bilan vaziyatni tasavvur qiling. Dunyoda siz bilan bir xil ism, ko'z rangi, yoshi, bo'yi, soch rangi va boshqalarga ega bo'lgan odam bordir. Ya'ni, siz ko'p jihatdan o'xshashsiz, lekin siz hali ham egizak emassiz va ayniqsa bir xil odam emassiz. Operator ikkita ob'ektni solishtirish uchun foydalanganda taxminan bir xil mantiqni qo'llaydi. Ammo dasturingizda boshqa mantiq kerak bo'lsa-chi? Misol uchun, agar sizning dasturingiz DNK tahlilini simulyatsiya qilsa. U ikki kishining DNK kodini solishtirib, ularning egizak ekanligini aniqlashi kerak. car2 Tenglar va satrlarni taqqoslash - 2==
public class Man {

   int 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 == man2);
   }
}
Konsol chiqishi:

false
Natija bir xil bo'lishi mantiqan to'g'ri keladi (axir biz hech narsani o'zgartirmadik), lekin hozir biz bundan mamnun emasmiz! Darhaqiqat, haqiqiy hayotda DNK tahlili biz egizaklar bilan yuzma-yuz kelayotganimizni yuz foiz kafolatlaydi. Ammo bizning dasturimiz va operatorimiz ==boshqacha aytadi. Qanday qilib biz bu xatti-harakatni o'zgartirishimiz va agar DNK testlari mos kelsa, dastur to'g'ri natija berishiga ishonch hosil qilishimiz mumkin? Shu maqsadda Java-da maxsus usul yaratilgan - equals() .

Java-da Equals() usuli

toString()Biz ilgari muhokama qilgan usul singari , equals() Java tilidagi eng muhim sinf bo'lgan sinfga tegishli bo'lib Object, boshqa barcha sinflar undan olinadi. Biroq, equals() o'zi bizning dasturimizning xatti-harakatlarini hech qanday tarzda o'zgartirmaydi:
public class Man {

   String dnaCode;

   public static void main(String[] args) {

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

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

       System.out.println(man1.equals(man2));
   }
}
Konsol chiqishi:

false
Aynan bir xil natija, unda bu usul nima uchun kerak? :/ Hammasi oddiy. Gap shundaki, endi biz ushbu usulni sinfning o'zida qo'llanganidek ishlatdik Object. Va agar biz sinf kodiga kirsak Objectva unda ushbu usul qanday amalga oshirilganini va u nima qilishini ko'rib chiqsak, biz quyidagilarni ko'ramiz:
public boolean equals(Object obj) {
   return (this == obj);
}
Bu bizning dasturimizning xatti-harakati o'zgarmasligining sababidir! Sinfning equals() usuli ichida Objectbir xil mos yozuvlar taqqoslash mavjud ==. Ammo bu usulning hiylasi shundaki, biz uni bekor qilishimiz mumkin. Qayta belgilash bu bizning sinfimizda o'z tenglar() usulingizni yozish Manva uni biz xohlagan tarzda tutishni anglatadi! man1.equals(man2)Endi biz chek bilan bir xil ishni bajarishidan qoniqmadik man1 == man2. Bu vaziyatda biz nima qilamiz:
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));

   }
}
Konsol chiqishi:

true
Mutlaqo boshqacha natija! Standart usul o'rniga o'zimizning equals() usulini yozish orqali biz to'g'ri xatti-harakatga erishdik: endi agar ikkita odam bir xil DNK kodiga ega bo'lsa, dastur bizga: "DNK tahlili ularning egizak ekanligini ko'rsatdi" deydi va haqiqatni qaytaradi! Sinflaringizdagi equals() usulini bekor qilish orqali siz ob'ektni taqqoslash uchun kerakli mantiqni osongina yaratishingiz mumkin. Biz ob'ektlarni solishtirishga faqat umumiy ma'noda to'xtaldik. Oldinda bizda bu mavzu bo'yicha alohida katta ma'ruza bo'ladi (agar qiziqsangiz, uni hozir tezda o'qishingiz mumkin).

Java'da string solishtirish - String solishtirish

Nega biz satrlarni taqqoslashni hamma narsadan alohida ko'rib chiqamiz? Aslida, dasturlashdagi chiziqlar butunlay boshqacha hikoya. Birinchidan, agar siz insoniyat tomonidan yozilgan barcha Java dasturlarini olsangiz, ulardagi ob'ektlarning taxminan 25% ulardan iborat. Shuning uchun bu mavzu juda muhim. Ikkinchidan, satrlarni taqqoslash jarayoni boshqa ob'ektlardan juda farq qiladi. Keling, oddiy misolni ko'rib chiqaylik:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1 == s2);
   }
}
Konsol chiqishi:

false
Lekin nega yolg'on? Chiziqlar aynan bir xil, so'zma-so'z:/ Siz taxmin qilishingiz mumkin: bu operator == havolalarni solishtirayotgani uchun! Axir, s1ularning s2xotirasida turli xil manzillar mavjud. Agar bu fikr sizga kelgan bo'lsa, keling, misolimizni takrorlaymiz:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = "JavaRush is the best site to learn Java!";
       System.out.println(s1 == s2);
   }
}
Endi bizda ikkita havola mavjud, ammo natija teskarisiga o'zgardi: Konsol chiqishi:

true
To'liq chalkashmisiz? :) Keling, buni aniqlaylik. Operator ==aslida xotiradagi manzillarni solishtiradi. Bu qoida har doim ishlaydi va bunga shubha qilishning hojati yo'q. Bu shuni anglatadiki, agar s1 == s2u rost bo'lsa, bu ikki satr xotirada bir xil manzilga ega. Va haqiqatan ham shunday! Satrlarni saqlash uchun maxsus xotira maydoni bilan tanishish vaqti keldi - string pool ( String pool) Tenglar va satrlarni taqqoslash - 3String puli - bu dasturingizda yaratgan barcha satr qiymatlarini saqlash uchun maydon. U nima uchun yaratilgan? Yuqorida aytib o'tilganidek, satrlar barcha ob'ektlarning katta qismini egallaydi. Har qanday katta dasturda juda ko'p qatorlar yaratiladi. Xotirani tejash uchun bu kerak bo'ladi String Pool- u erda kerakli matn bilan chiziq joylashtiriladi va kelajakda yangi yaratilgan havolalar bir xil xotira maydoniga tegishli bo'lib, har safar qo'shimcha xotira ajratishning hojati yo'q. Har safar yozganingizda String = “........”, dastur string hovuzida shunday matnli satr mavjudligini tekshiradi. Agar mavjud bo'lsa, yangisi yaratilmaydi. Va yangi havola ushbu satr saqlanadigan string hovuzidagi bir xil manzilga ishora qiladi. Shuning uchun, biz dasturda yozganimizda
String s1 = "JavaRush is the best site to learn Java!";
String s2 = "JavaRush is the best site to learn Java!";
havola s2aynan bir xil joyga ishora qiladi s1. Birinchi buyruq bizga kerak bo'lgan matn bilan string hovuzida yangi qator yaratdi va ikkinchisiga kelganda, u shunchaki bir xil xotira maydoniga ishora qildi s1. Xuddi shu matn bilan siz yana kamida 500 ta satr qilishingiz mumkin, natija o'zgarmaydi. STOP. Lekin nega bu misol avvalroq biz uchun ishlamadi?
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1 == s2);
   }
}
O'ylaymanki, intuitiv ravishda, siz allaqachon sabab nima ekanligini taxmin qildingiz :) Keyingi o'qishdan oldin taxmin qilishga harakat qiling. Bu ikki satr boshqacha yaratilganligini ko'rishingiz mumkin. Biri operator yordamida new, ikkinchisi esa usiz. Aynan shu sabab. Yangi operator ob'ektni yaratishda u uchun xotirada yangi maydonni majburiy ravishda ajratadi . , bilan yaratilgan qator esa newbilan tugamaydi String Pool: matni String Pool'a dan bir xil satr bilan aynan bir xil bo'lsa ham, alohida ob'ektga aylanadi. Ya'ni, agar biz quyidagi kodni yozsak:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = "JavaRush is the best site to learn Java!";
       String s3 = new String("JavaRush is the best site to learn Java!");
   }
}
Xotirada u quyidagicha ko'rinadi: Tenglar va qatorlarni taqqoslash - 4Va har safar yangi ob'ekt yaratilganda, newyangi satrlar ichidagi matn bir xil bo'lsa ham, xotirada yangi maydon ajratiladi! Biz operatorni ajratdik ==, lekin bizning yangi do'stimiz - equals() usuli haqida nima deyish mumkin?
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1.equals(s2));
   }
}
Konsol chiqishi:

true
Qiziqarli. Biz aniq nimani bilamiz s1va s2xotiraning turli sohalariga ishora qilamiz. Ammo, shunga qaramay, equals() usuli ular teng ekanligini aytadi. Nega? Esingizda bo'lsin, yuqorida biz sizning sinfingizda teng () usulini bekor qilish mumkinligini aytdik, shunda u ob'ektlarni kerakli tarzda taqqoslaydi? Ular sinf bilan shunday qilishdi String. Unda bekor qilingan teng() usuli mavjud. Va u havolalarni emas, balki satrlardagi belgilar ketma-ketligini taqqoslaydi. Va agar satrlardagi matn bir xil bo'lsa, ular qanday yaratilganligi va qaerda saqlanganligi muhim emas: string hovuzida yoki alohida xotira maydonida. Taqqoslash natijasi to'g'ri bo'ladi. Aytgancha, Java sizga harflarni sezmagan holda satrlarni to'g'ri taqqoslash imkonini beradi. Oddiy holatda, agar siz satrlardan birini yozsangiz, masalan, bosh harflar bilan, taqqoslash natijasi noto'g'ri bo'ladi:
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JAVARUSH - ЛУЧШИЙ САЙТ ДЛЯ ИЗУЧЕНИЯ JAVA!");
       System.out.println(s1.equals(s2));
   }
}
Konsol chiqishi:

false
Bunday holda, sinfda Stringusul mavjud equalsIgnoreCase(). Taqqoslashda asosiy narsa ularning holati emas, balki aniq belgilar ketma-ketligi bo'lsa, siz undan foydalanishingiz mumkin. Masalan, bu ikkita elektron pochta manzilini solishtirganda foydali bo'ladi:
public class Main {

   public static void main(String[] args) {

       String address1 = "Moscow, Academician Korolev street, 12";
       String address2 = new String("Г. МОСКВА, УЛ. АКАДЕМИКА КОРОЛЕВА, ДОМ 12");
       System.out.println(address1.equalsIgnoreCase(address2));
   }
}
Bunday holda, biz bir xil manzil haqida gapirayotganimiz aniq, shuning uchun usuldan foydalanish equalsIgnoreCase()to'g'ri qaror bo'ladi.

String.intern() usuli

Sinfning Stringyana bir qiyin usuli bor - intern(); Usul intern()to'g'ridan-to'g'ri "om" bilan ishlaydi String Pool. intern()Agar siz stringda usulni chaqirsangiz , u:
  • String hovuzida ushbu matnli satr bor yoki yo'qligini tekshiradi
  • Agar mavjud bo'lsa, hovuzda unga havolani qaytaradi
  • Agar yo'q bo'lsa, u ushbu matnli qatorni string hovuziga joylashtiradi va unga havolani qaytaradi.
Usulni intern()new orqali yaratilgan satr ma'lumotnomasiga qo'llash orqali biz uni String Pool"a" orqali string havolasi bilan solishtirishimiz mumkin ==.
public class Main {

   public static void main(String[] args) {

       String s1 = "JavaRush is the best site to learn Java!";
       String s2 = new String("JavaRush is the best site to learn Java!");
       System.out.println(s1 == s2.intern());
   }
}
Konsol chiqishi:

true
Ilgari, biz ularni holda taqqoslaganimizda intern(), natija noto'g'ri edi. Endi usul “JavaRush – Java tilini o‘rganish uchun eng yaxshi sayt!”intern() matni bilan chiziq bor-yo‘qligini tekshirdi. simli hovuzda. Albatta, u erda: biz uni yozganimizda yaratganmiz
String s1 = "JavaRush is the best site to learn Java!";
s1Usul tomonidan qaytarilgan havola va havola xotiraning bir xil sohasiga ishora qilishi tekshirildi s2.intern()va, albatta, ular shunday qiladi :) Xulosa qilish, eslab qolish va asosiy qoidadan foydalanish: Satrlarni solishtirish uchun DOIMO teng() dan foydalaning. usul! Satrlarni taqqoslashda siz deyarli har doim havolalarni, xotira maydonlarini va hokazolarni emas, balki ularning matnini solishtirishni nazarda tutasiz. equals() usuli aynan sizga kerak bo'lgan narsani bajaradi. O'zingiz o'rganishingiz uchun quyidagi havolalar mavjud:
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION