ความแตกต่างระหว่างString#equals
วิธีการและString#contentEquals
วิธีการคืออะไร?
ความแตกต่างระหว่างString#equals
วิธีการและString#contentEquals
วิธีการคืออะไร?
คำตอบ:
String#equals()
ไม่เพียง แต่เปรียบเทียบเนื้อหา String แต่ยังตรวจสอบว่าวัตถุอื่น ๆ String
ยังเป็นตัวอย่างของ String#contentEquals()
เปรียบเทียบเฉพาะเนื้อหา (ลำดับตัวอักษร) และไม่ได้ตรวจสอบว่าวัตถุอื่น ๆ String
ยังเป็นตัวอย่างของ มันสามารถเป็นอะไรก็ได้ตราบเท่าที่มันคือการดำเนินการCharSequence
ซึ่งครอบคลุมอ่าวString
, StringBuilder
, StringBuffer
, CharBuffer
ฯลฯ
==
ดำเนินการจะอนุญาตให้คุณเปรียบเทียบการอ้างอิงไม่ใช่เนื้อหาของวัตถุสองรายการ
==
กล่าวถึงคือ JavaScript เท่านั้น มันไม่เคยพูดถึงเกี่ยวกับ Java
==
ใน JavaScript มีความคลาดเคลื่อนมากกว่าcontentEquals
ซึ่งจะไม่แตะหมายเลข) แต่คุณถูกต้องเกี่ยวกับการequals
ตรวจสอบการจับคู่ประเภทที่แน่นอนด้วยStrings
(คลาสอื่น ๆ อาจจะหลวมกว่าด้วยequals
วิธีการของพวกเขา) .
ที่จะนำมันได้อย่างง่ายดาย: String.contentEquals()
เป็นพี่ชายชาญฉลาดเพราะมันสามารถเป็นอิสระมากขึ้นในการดำเนินงานมากกว่าString.equals()
String.equals()
มีสาเหตุบางประการที่มีString.contentEquals()
วิธีแยกต่างหาก เหตุผลที่สำคัญที่สุดที่ฉันคิดคือ:
equals
วิธีการจะต้องมีการสะท้อนกลับ นั่นหมายความว่า: x.equals(y) == y.equals(x)
. นี่ก็หมายความว่าจะต้องเป็นเช่นเดียวกับaString.equals(aStringBuffer)
aStringBuffer.equals(aString)
สิ่งนี้จะต้องใช้นักพัฒนา Java API เพื่อให้มีการใช้งานพิเศษสำหรับ Strings ในequals()
วิธีการของ StringBuffer, StringBuilder และ CharSequence เช่นกัน นี่จะเป็นระเบียบนี่คือที่String.contentEquals
มาใน. นี้เป็นวิธีการแบบสแตนด์อโลนที่ไม่ได้มีการปฏิบัติตามข้อกำหนดที่เข้มงวดและกฎระเบียบObject.equals
สำหรับ ด้วยวิธีนี้คุณสามารถใช้ความรู้สึกของ"เนื้อหาเท่ากัน"ได้อย่างอิสระมากขึ้น สิ่งนี้ช่วยให้คุณทำการเปรียบเทียบอย่างชาญฉลาดระหว่าง StringBuffer และสตริงตัวอย่างเช่น
และจะพูดในสิ่งที่แตกต่างคือ:
String.contentEquals()
สามารถเปรียบเทียบเนื้อหาของ a String
, a StringBuilder
, a StringBuffer
, a CharSequence
และคลาสที่ได้รับทั้งหมดของสิ่งเหล่านี้ หากพารามิเตอร์เป็นประเภท String ให้String.equals()
ทำการเรียกใช้งาน
String.equals()
เปรียบเทียบวัตถุสตริงเท่านั้น วัตถุประเภทอื่น ๆ ทั้งหมดถือว่าไม่เท่ากัน
String.contentEquals()
สามารถเปรียบเทียบStringBuffer
และStringBuilder
ในวิธีที่ชาญฉลาด มันไม่ได้เรียกtoString()
วิธีหนักซึ่งคัดลอกเนื้อหาทั้งหมดไปยังวัตถุ String ใหม่ แต่จะเปรียบเทียบกับchar[]
อาเรย์พื้นฐานซึ่งยอดเยี่ยม
คำตอบนี้ถูกโพสต์แล้วโดยdbwแต่เขาลบมันออกไป แต่เขาก็มีบางจุดที่ถูกต้องมากสำหรับความแตกต่างในขณะที่เปรียบเทียบเวลาดำเนินการข้อยกเว้นที่ถูกโยน
ถ้าคุณดูที่รหัสที่มาเท่ากับสตริง #และString # contentEqualsเป็นที่ชัดเจนว่ามีสองวิธีแทนที่สำหรับString#contentEquals
หนึ่งซึ่งใช้เวลาและอื่น ๆStringBuilder
ความแตกต่างระหว่างพวกเขาCharSequence
String#contentEquals
จะโยน NPE หากข้อโต้แย้งที่ให้มามีnull
แต่String#equals
จะกลับมาfalse
String#equals
เปรียบเทียบเนื้อหาเฉพาะเมื่ออาร์กิวเมนต์ที่จัดมาให้เป็นinstance of String
อย่างอื่นก็จะกลับมาfalse
ในกรณีอื่น ๆ ทั้งหมด แต่ในมืออื่น ๆการตรวจสอบเนื้อหาของวัตถุทั้งหมดที่ใช้อินเตอร์เฟซString#contentEquals
CharSequence
คุณสามารถปรับแต่งรหัสเพื่อให้String#contentEquals
ส่งคืนผลลัพธ์ที่ไม่ถูกต้องหรือผลลัพธ์ที่คุณต้องการโดยแทนที่equals
วิธีการโต้แย้งที่ส่งผ่านตามที่แสดงด้านล่าง แต่คุณไม่สามารถปรับแต่งค่าเหล่านั้นString#equals
ได้
โค้ดด้านล่างจะสร้างtrue
ตราบs
ใดstring
ที่มีอักขระใด ๆที่มีความยาว 3 อักขระ
String s= new String("abc");// "abc";
System.out.println(s.contentEquals(new CharSequence()
{
@Override
public CharSequence subSequence(int arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public int length() {
// TODO Auto-generated method stub
return 0;
}
@Override
public char charAt(int arg0) {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean equals(Object obj)
{
return true;
}
}));
String#contentEquals
จะช้าลงString#Equals
ในกรณีที่อาร์กิวเมนต์ที่ให้มามีinstance of String
ความยาวString
เท่ากัน แต่เนื้อหาไม่เท่ากัน
ตัวอย่างเช่นถ้าสตริงString s = "madam"
และString argPassed = "madan"
จากนั้นs.contentEquals(argPassed)
จะใช้เวลาในการดำเนินการเกือบสองเท่าในกรณีนี้เมื่อเทียบกับs.equals(argPassed)
หากความยาวเนื้อหาไม่เหมือนกันสำหรับทั้งสองสตริงฟังก์ชันString#contentEquals
จะมีประสิทธิภาพที่ดีกว่าString#Equals
ในเกือบทุกกรณีที่เป็นไปได้
อีกหนึ่งจุดที่จะเพิ่มคำตอบของเขา
String#contentEquals
ของString
วัตถุจะเปรียบเทียบกับStringBuilder
เนื้อหาและให้ผลลัพธ์ที่เหมาะสมในขณะที่String#Equals
จะกลับมาfalse
String
equals(Object o)
วิธีการเรียนไม่String
เปรียบเทียบเท่านั้น แต่contentEquals(CharSequence cs)
การตรวจสอบสำหรับการเรียนขยายAbstractStringBuilder
เช่น StringBuffer
, StringBuilder
และString
ชั้นยัง (พวกเขาทั้งหมดเป็นประเภทCharSequence
)
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));
เอาท์พุท:
false
true
เอาต์พุตของ stmt แรกเป็นfalse
เพราะbuilder
ไม่ใช่ชนิดString
เพื่อให้equals()
ผลตอบแทนfalse
แต่contentEquals()
การตรวจสอบเนื้อหาของทุกประเภทเช่นที่StringBuilder
, StringBuffer
, และเป็นเนื้อหาเดียวกันด้วยเหตุนี้String
true
contentEquals
จะโยนNullPointerException
หากอาร์กิวเมนต์ที่ให้มาnull
แต่equals()
จะกลับเท็จเพราะเท่ากับ () ตรวจสอบ instanceOf (if (anObject instance of String)
) null
ซึ่งผลตอบแทนที่เป็นเท็จถ้าอาร์กิวเมนต์เป็นcontentEquals(CharSequence cs)
:
java.lang.CharacterSequence
(เช่นCharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
)equals(Object anObject)
:
java.lang.String
เท่านั้นRTFC :)
เนื่องจากการอ่านแหล่งข้อมูลเป็นวิธีที่ดีที่สุดในการทำความเข้าใจฉันกำลังแบ่งปันการใช้งานของทั้งสองวิธี (เช่น jdk 1.7.0_45)
public boolean contentEquals(CharSequence cs) {
if (value.length != cs.length())
return false;
// Argument is a StringBuffer, StringBuilder
if (cs instanceof AbstractStringBuilder) {
char v1[] = value;
char v2[] = ((AbstractStringBuilder) cs).getValue();
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
// Argument is a String
if (cs.equals(this))
return true;
// Argument is a generic CharSequence
char v1[] = value;
int i = 0;
int n = value.length;
while (n-- != 0) {
if (v1[i] != cs.charAt(i))
return false;
i++;
}
return true;
}
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
มีวิธีอื่นของ String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()
และcontentEquals()
มีสองวิธีการในString
ชั้นเรียนเพื่อเปรียบเทียบสองstrings
และมีstring
StringBuffer
พารามิเตอร์ของcontentEquals()
Are และStringBuffer
ใช้เพื่อเปรียบเทียบสองรายการและใช้เพื่อเปรียบเทียบเนื้อหาของและString(charSequence)
equals()
strings
contentEquals()
String
StringBuffer
และ
วิธีการcontentEquals
และ equals
ก็
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
นี่คือรหัสที่อธิบายถึงทั้งสองวิธี
public class compareString {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
boolean result1 = str1.equals(str2); // works nice and returns true
System.out.println(" str1.equals(str2) - "+ result1);
boolean result2 = str1.equals(sb1); // works nice and returns false
System.out.println(" str1.equals(sb1) - "+ result2);
boolean result3 = str1.contentEquals(sb1); // works nice and returns true
System.out.println(" str1.contentEquals(sb1) - "+ result3);
boolean result4 = str1.contentEquals(sb2); // works nice and returns false
System.out.println(" str1.contentEquals(sb2) - "+ result4);
boolean result5 = str1.contentEquals(str2); // works nice and returns true
System.out.println(" str1.contentEquals(str2) - "+ result5);
}
}
เอาท์พุท:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
String # เท่ากับใช้ Object เป็นอาร์กิวเมนต์และตรวจสอบว่าเป็นอินสแตนซ์ของ String วัตถุหรือไม่ หากวัตถุอาร์กิวเมนต์เป็นวัตถุสตริงก็จะเปรียบเทียบตัวละครเนื้อหาโดยตัวละคร มันจะคืนค่าจริงในกรณีเนื้อหาของวัตถุสตริงทั้งสองเหมือนกัน
String # contentEqualsใช้ CharSequence อินเตอร์เฟสเป็นอาร์กิวเมนต์ CharSequence สามารถใช้งานได้ 2 วิธีโดยใช้ i) String class หรือ (ii) AbstractStringBuilder (คลาสพาเรนต์ของ StringBuffer, StringBuilder)
ในcontentEquals () ความยาวถูกเปรียบเทียบก่อนการตรวจสอบอินสแตนซ์ของวัตถุใด ๆ ถ้าความยาวเท่ากันก็จะตรวจสอบว่าวัตถุนั้นเป็นตัวอย่างของ AbstractStringBuilder หรือไม่ ถ้าเป็นเช่นนั้น (เช่น StringBuffer หรือ StringBuilder) เนื้อหาจะถูกตรวจสอบตัวอักษรโดยตัวละคร ในกรณีที่อาร์กิวเมนต์เป็นตัวอย่างของวัตถุ String แล้ว String # เท่ากับเรียกจาก String # contentEquals
ดังนั้นในระยะสั้น
String # เท่ากับเปรียบเทียบตัวละครเนื้อหาโดยตัวละครในกรณีที่อาร์กิวเมนต์เป็นวัตถุสตริงเช่นกัน และString # contentEqualsเปรียบเทียบเนื้อหาในกรณีที่วัตถุอาร์กิวเมนต์ใช้อินเตอร์เฟซ CharSequence
String # contentEquals ช้าลงในกรณีที่เราเปรียบเทียบเนื้อหาสตริงที่มีความยาวเท่ากันสองรายการเป็น String # contentEquals จะเรียก String # เท่ากับภายในสำหรับ String วัตถุ
ในกรณีที่เราพยายามเปรียบเทียบวัตถุที่มีความยาวเนื้อหาต่างกัน (พูดว่า "abc" กับ "abcd") ดังนั้น String # contentEquals จะเร็วกว่า String # เท่ากับ เนื่องจากมีการเปรียบเทียบความยาวก่อนการตรวจสอบวัตถุใด ๆ
contentEquals()
ตรวจสอบวิธีการนี้เป็นเนื้อหาจะเหมือนกันระหว่างString
, StringBuffer
ฯลฯ ซึ่งชนิดของลำดับถ่านบาง
BTW เหตุผลทางประวัติศาสตร์สำหรับความแตกต่างคือสตริงเดิมไม่มีซูเปอร์คลาสดังนั้น String.equals () รับสตริงเป็นอาร์กิวเมนต์ เมื่อ CharSequence ถูกนำมาใช้เป็น superclass ของ String มันจำเป็นต้องมีการทดสอบความเท่าเทียมกันของตัวเองที่ทำงานในทุกการใช้งาน CharSequence และที่จะไม่ชนกับ equals () ที่ใช้งานโดย String ... ดังนั้นเราจึงได้ CharSequence.contentEquals ( ) ซึ่งสืบทอดโดย String
หาก CharSequence มีอยู่ใน Java 1.0 เราก็จะมีเพียง CharSequence.equals () และ String จะใช้มันเพียงอย่างเดียว
อ่าความสุขของการพัฒนาภาษา ...
==
(contentEquals) และ===
(เท่ากับ) ใน javascript หรือไม่