==
operatoru ilə iki referansı müqayisə etdikdə hər iki referansın da eyni obyektə işarə edib etmədiyini müqayisə edir. equals()
metodu ilə müqayisə etdikdə isə referansların dəyərlərini bir-biri ilə müqayisə edir. String
classi equals()
metodunu override edir deyə eyni dəyərə malik iki Stringi equals()
ilə müqayisə etdikdə nəticə true
verir. Ancaq StringBuilder
classı equals()
metodunu override etmir, ona görə də eyni dəyərə malik StringBuilder
referanslarını equals()
ilə müqayisə etdikdə nəticə false
verir. Ümumiyyətlə əgər hər hansı bir class equals()
metodunu override etmirsə, həmin classın referansı üzərindən equals()
metodu çağırılsa, bu zaman Object classının equals()
metodu çağırılır. Çünki bütün classlar aşkar şəkildə qeyd olunmasa da Object
classından törəmədirlər və onun metodlarını varis alırlar. Bu mövzu Chapter 5’də ayrıca izah ediləcəkdir, hələlik isə bilməniz yetərlidir ki, Object
classının equals()
metodu dəyərləri müqayisə etmir, referansları müqayisə edir. Əgər referanslar eyni obyektə işarə edirsə, true
qaytarır, digər hallarda isə false
qaytarır.
public class Book { public static void main(String[] args) { Book b1 = new Book (); Book b2 = new Book (); Book b3 = b1; System.out.println(b1 == b3); // true System.out.println(b1 == b2); // false System.out.println(b1.equals(b2)); // false } }
Book
classı göründüyü kimi equals()
metodunu override etmir, belə olan halda bu class üçün ==
və equals()
eyni cür işləyir və eyni nəticəni verir.
İndi isə String
və StringBuilder
ilə bağlı nümunələrə baxaq.
StringBuilder example:
StringBuilder one = new StringBuilder("java"); StringBuilder two = new StringBuilder("java"); System.out.println(one == two); // false System.out.println(one.equals(two)); // false StringBuilder three = one.append(two); System.out.println(one == three); // true System.out.println(one.equals(three)); // true System.out.printf("%s,%s,%s%n",one,two,three); // javajava, java, javajava
String example:
String x = "Hello World"; String y = "Hello World"; System.out.println(x == y); // true System.out.println(x.equals(y)); // true String z = " Hello World".trim(); System.out.println(x == z); // false System.out.println(x.equals(z)); // true
String
immutable`dır və String literal dəyərləri String Pool’da saxlanılır. JVM yaddaşda eyni literaldan ancaq bir ədəd yaradır. Yuxarıdakı nümunədə "Hello World"
bir dəfə yaradılır və pool`da saxlanılır. x
və y
referanslarının hər ikisi də həmin o obyektə işarə edir.
" Hello World".trim();
literal dəyər olmadığından pool`da saxlanılmır, ona görə də x
və z
eyni obyektə işarə etmirlər, amma eyni dəyərə malikdirlər. Burada da incə bir məqam var, aşağıdakı kod nümunəsinə baxaq:
String x = "Hello World"; String y = "Hello World".trim(); String z = "Hello World".toString(); System.out.println(x==y); // true System.out.println(x==z); // true
Bu mövzu ətraflı şəkildə coderanch forumunda müzakirə edilib:
http://www.coderanch.com/t/652234/ocajp/certification/Understanding-Equality-page-Java-OCA
String metodlar üzərindən bəzi nümunələrə baxaq:
String s1 = "test"; String s2 = s1.substring(0); String s3 = s1.replace("e","e"); String s3_ = s1.replace('e','e'); String s4 = "test".trim(); String s5 = "test ".trim(); String s6 = s1.toString(); System.out.printf("substring: %s==%s returns %b%n", s1, s2, s1==s2); System.out.printf("replace1: %s==%s returns %b%n", s1, s3, s1==s3); System.out.printf("replace2: %s==%s returns %b%n", s1, s3_, s1==s3_); System.out.printf("trim1: %s==%s returns %b%n", s1, s4, s1==s4); System.out.printf("trim2: %s==%s returns %b%n", s1, s5, s1==s5); System.out.printf("toString: %s==%s returns %b%n", s1, s6, s1==s6);
Output:
substring: test==test returns true
replace1: test==test returns false
replace2: test==test returns true
trim1: test==test returns true
trim2: test==test returns false
toString: test==test returns true
P.S. replace()
char
ilə olanda true
qaytarır.
Primitiv wrapper classların (Integer, Double, Float
və s.) equals()
metodu ilə istifadəsi zamanı aşağıdakı 3 qayda keçərlidir:
- symmetric ⇒
a.equals(b)
iləb.equals(a)
eyni nəticəni qaytarır; - transitive ⇒ əgər
a.equals(b)
vəb.equals(c)
geriyətrue
qaytarırsa, o zamana.equals(c)
dətrue
qaytaracaq; - reflexive ⇒
a.equals(a)
geriyətrue
qaytarır.
Aşağıdakı şəkildəki suala Enthuware test bankında rast gələcəksiniz. İmtahanda əvvəllər “drag-drop” tipli suallar olsa da hazırda bu formatda suallar imtahan testlərindən çıxarılıb. Amma bu sualın içərisində maraqlı məqamlar var, faydalı olacağından qeyd etməyi zəruri bildim.
i1 == i2
– geriyəfalse
qaytarır, çünki referanslar fərqli obyektlərə işarə edir.i1 == i3
– geriyətrue
qaytarır, çünkii3
primitiv tipdə olduğundani1
də “unboxed” edilərək primitiv tipə çevirilir və sonra müqayisə aparılır.i1 == b1
– compile olunmur, çünkii1
vəb1
referansları eyni ierarxiyada olmayan classlara məxsusdur və compiler compile zamanı bunu tutur və başa düşür ki, bu referanslar eyni obyektə işarə edə bilməzlər.i1.equals(i2)
– geriyətrue
qaytarır, çünki hər ikisiInteger
obyektidir və dəyərləri də eynidir.i1.equals(b1)
vəi1.equals(g1)
– geriyəfalse
qaytarır, çünki müqayisə olunan dəyərlər fərqli classlara aiddir.==
ilə müqayisədən fərqli olaraqequals()
ilə müxtəlif classlara işarə edən referansların müqayisəsi zamanı compile xətası baş vermir, çünkiequals()
metodu parametr olaraqObject
tipi qəbul edir. Bütün wrapper classlarınequals()
metodunun gövdəsində ilk olaraq müqayisə edilən obyektlərin eyni classa aid olub olmadığı yoxlanılır. Əgər eyni classa aid deyilsə, o zaman dəyərlərin yoxlanılması aparılmır, birbaşafalse
qaytarılır.Integer
metodununequals()
metoduna baxsaq bu proses aydın olacaq:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
Wrapper classlar ilə bağlı digər maraqlı bir nümunəyə Coderanch forumunda rast gələ bilərsiniz:
public static void main(String[] args) { int myInt1 = 10; Integer myInteger1 = 10; Integer myInteger2 = 10; Integer myInteger3 = new Integer(10); Short myShort1 = 10; Number myNumber1 = 10; Double myDouble1 = 10.0; Double myDouble2 = 10; // DOES NOT COMPILE System.out.println(myInt1 == myInteger1); // true System.out.println(myInt1 == myInteger3); // true System.out.println(myInt1 == myShort1); // true System.out.println(myInt1 == myNumber1); // DOES NOT COMPILE System.out.println(myInt1 == myDouble1); // true System.out.println(myInteger1 == myInteger2); // true System.out.println(myInteger1 == myInteger3); // false System.out.println(myInteger1 == myShort1); // DOES NOT COMPILE System.out.println(myInteger1 == myNumber1); // true System.out.println(myInteger1 == myDouble1); // DOES NOT COMPILE System.out.println(myShort1 == 10.0); // true System.out.println(myShort1 == myNumber1); // false System.out.println(myShort1 == myDouble1); // DOES NOT COMPILE }
Əlavə olaraq aşağıdakı nümunələrə baxmağınızda da fayda var:
String s1 = new String(); String s2 = new String(); System.out.println(s1.equals(s2)); // true, çünki equals metodunu implement edir StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); System.out.println(sb1.equals(sb2)); // false, çünki equals metodunu implement etmir ArrayList l1 = new ArrayList(); ArrayList l2 = new ArrayList(); System.out.println(l1.equals(l2)); // true, çünki equals metodunu implement edir List<StringBuilder> l3 = new ArrayList<>(); List<StringBuilder> l4 = new ArrayList<>(); l3.add(new StringBuilder("sb")); l4.add(new StringBuilder("sb")); System.out.println(l3.equals(l4)); // false List<String> l5 = new ArrayList<>(); List<String> l6 = new ArrayList<>(); l5.add(new String("str")); l6.add(new String("str")); System.out.println(l5.equals(l6)); // true Object o1 = new Object(); Object o2 = new Object(); System.out.println(o1.equals(o2)); // false, səbəbi yuxarıda qeyd edilib String str1 = "one"; String str2 = "two"; System.out.println(str1.equals(str1 = str2)); // false System.out.println(str1.equals(str2 = str1)); // true String s1 = "s1"; String s = "s"; System.out.println(s1 == s + 1); // false System.out.println(s1 == "s" + 1); // true final String e1 = "e1"; final String e = "e"; System.out.println(e1 == e + 1); // true String s1 = "java"; StringBuilder s2 = new StringBuilder("java"); if(s1 == s2) // DOES NOT COMPILE System.out.println("1"); if(s1.equals(s2)) // false System.out.println("2"); String a = ""; String b = "2cfalse"; a += 2; a += 'c'; a += false; System.out.println(a == "2cfalse"); // false System.out.println(a.equals("2cfalse")); // true System.out.println(b == "2cfalse"); // true StringBuilder strb = new StringBuilder(5); String str = ""; str.equals(strb); // false str.equals(strb.toString()); // true
[topics lang=az]