ความแตกต่างระหว่าง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จะกลับมาfalseString#equalsเปรียบเทียบเนื้อหาเฉพาะเมื่ออาร์กิวเมนต์ที่จัดมาให้เป็นinstance of Stringอย่างอื่นก็จะกลับมาfalseในกรณีอื่น ๆ ทั้งหมด แต่ในมืออื่น ๆการตรวจสอบเนื้อหาของวัตถุทั้งหมดที่ใช้อินเตอร์เฟซString#contentEqualsCharSequenceคุณสามารถปรับแต่งรหัสเพื่อให้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 Stringequals(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, และเป็นเนื้อหาเดียวกันด้วยเหตุนี้Stringtrue
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และมีstringStringBuffer
พารามิเตอร์ของcontentEquals()Are และStringBuffer ใช้เพื่อเปรียบเทียบสองรายการและใช้เพื่อเปรียบเทียบเนื้อหาของและString(charSequence)equals()stringscontentEquals()StringStringBufferและ
วิธีการ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 หรือไม่