Sự khác biệt giữa String#equalsphương pháp và String#contentEqualsphương pháp là gì?
Sự khác biệt giữa String#equalsphương pháp và String#contentEqualsphương pháp là gì?
Câu trả lời:
Các String#equals()không chỉ so sánh nội dung của String, mà còn kiểm tra nếu đối tượng khác cũng là một thể hiện của một String. Các String#contentEquals()chỉ so sánh nội dung (chuỗi ký tự) và không không kiểm tra xem đối tượng khác cũng là một thể hiện của String. Nó có thể là bất cứ điều gì miễn là nó là một thực hiện CharSequencetrong đó bao gồm ao String, StringBuilder, StringBuffer, CharBuffervv
==toán tử sẽ chỉ cho phép bạn so sánh các tham chiếu không phải là nội dung của hai đối tượng.
==đề cập chỉ là JavaScript; nó không bao giờ được đề cập về Java.
==trong JavaScript lỏng hơn nhiều so với contentEquals, chẳng hạn như không chạm vào số), nhưng bạn đã đúng về equalsviệc kiểm tra loại khớp chính xác vớiStrings (các lớp khác có thể lỏng hơn với các loại trong equalsphương thức của chúng ) .
Nói một cách dễ dàng: String.contentEquals()là người anh em thông minh hơn String.equals(), bởi vì nó có thể tự do hơn trong việc thực hiện hơn String.equals().
Có một số lý do tại sao có một String.contentEquals()phương pháp riêng biệt . Lý do quan trọng nhất tôi nghĩ là:
equalsphương pháp này phải được phản. Điều đó có nghĩa là : x.equals(y) == y.equals(x). Điều này ngụ ý rằng aString.equals(aStringBuffer)sẽ phải giống như aStringBuffer.equals(aString). Điều này sẽ yêu cầu các nhà phát triển API Java thực hiện một số triển khai đặc biệt cho Chuỗi theo equals()phương thức StringBuffer, StringBuilder và CharSequence. Đây sẽ là một mớ hỗn độn.Đây là nơi String.contentEqualsđến. Đây là một phương pháp độc lập mà không phải làm theo các yêu cầu nghiêm ngặt và quy tắc cho Object.equals. Bằng cách này, bạn có thể thực hiện ý nghĩa "nội dung bình đẳng" một cách tự do hơn. Điều này cho phép bạn thực hiện so sánh thông minh giữa StringBuffer và String chẳng hạn.
Và để nói chính xác sự khác biệt là gì:
String.contentEquals()có thể so sánh nội dung của a String, a StringBuilder, a StringBuffer, a CharSequencevà tất cả các lớp dẫn xuất của các lớp này. Nếu tham số có kiểu String, thì String.equals()được thực thi.
String.equals()chỉ so sánh các đối tượng String. Tất cả các loại đối tượng khác được coi là không bằng nhau.
String.contentEquals()có thể so sánh StringBuffervà StringBuildermột cách thông minh. Nó không gọi toString()phương thức nặng , sao chép toàn bộ nội dung sang một đối tượng String mới. Thay vào đó, nó so sánh với các char[]mảng bên dưới , đó là tuyệt vời.
Câu trả lời này đã được đăng bởi dbw nhưng anh ta đã xóa nó nhưng anh ta có một số điểm rất hợp lệ cho sự khác biệt trong khi so sánh thời gian thực hiện, những ngoại lệ nào được đưa ra,
Nếu bạn nhìn vào mã nguồn String # bằng và String # contentEquals thì rõ ràng có hai phương thức được ghi đè cho String#contentEqualsmột phương thức lấy StringBuildervà phương thức khác CharSequence.
Sự khác biệt giữa chúng,
String#contentEqualssẽ ném NPE nếu đối số được cung cấp nullnhưng String#equalssẽ trả vềfalseString#equalschỉ so sánh nội dung khi đối số được cung cấp instance of Stringnếu không nó sẽ trả về falsetrong tất cả các trường hợp khác nhưng mặt khác String#contentEqualskiểm tra nội dung của tất cả các đối tượng thực hiện giao diện CharSequence.Bạn cũng có thể điều chỉnh mã để String#contentEqualstrả về kết quả sai hoặc kết quả bạn muốn bằng cách ghi đè equalsphương thức của đối số được truyền như dưới đây nhưng bạn không thể thực hiện các chỉnh sửa đó String#equals.
Mã bên dưới sẽ luôn tạo ratrue miễn là schứa bất kỳ stringký tự nào dài 3 ký tự
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#contentEqualssẽ chậm hơn String#Equalstrong trường hợp khi đối số được cung cấp là instance of Stringvà độ dài của cả hai Stringlà như nhau nhưng nội dung không bằng nhau.
Ví dụ nếu chuỗi là String s = "madam"và String argPassed = "madan"sau đó s.contentEquals(argPassed)sẽ mất gần gấp đôi thời gian thực hiện trong trường hợp này so vớis.equals(argPassed)
Nếu độ dài nội dung không giống nhau cho cả hai chuỗi thì hàm String#contentEqualssẽ có hiệu suất tốt hơn String#Equalstrong hầu hết các trường hợp có thể.
Thêm một điểm để thêm vào câu trả lời của anh ấy
String#contentEqualscủa một Stringđối tượng cũng sẽ so sánh với StringBuildernội dung và cung cấp kết quả phù hợp trong khi String#Equalssẽ trả vềfalse Stringequals(Object o)phương pháp lớp không chỉ Stringso sánh. Nhưng contentEquals(CharSequence cs)kiểm tra cho các lớp học kéo dài AbstractStringBuildertức StringBuffer, StringBuildervà Stringlớp cũng (Tất cả họ đều là những loại CharSequence).
String str = "stackoverflow";
StringBuilder builder = new StringBuilder(str);
System.out.println(str.equals(builder));
System.out.println(str.contentEquals(builder));đầu ra:
false
true
Kết quả của stmt đầu tiên là falsebởi vì builderkhông phải là loại Stringđể equals()trở về falsenhưng contentEquals()kiểm tra về nội dung của tất cả các loại như StringBuilder, StringBuffer, Stringvà như nội dung là giống nhau vì thế true.
contentEqualssẽ ném NullPointerExceptionnếu đối số được cung cấp là nullnhưng equals()sẽ trả về false vì hàm bằng () kiểm tra instanceOf ( if (anObject instance of String)) trả về false nếu đối số là null.contentEquals(CharSequence cs):
java.lang.CharacterSequence(ví dụ CharBuffer, Segment, String, StringBuffer, StringBuilder)equals(Object anObject):
java.lang.String chỉRTFC :)
Vì đọc nguồn là cách tốt nhất để hiểu về nó, tôi chia sẻ việc triển khai cả hai phương thức (kể từ 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;
}
Có một phương thức khác của String # contentEquals ():
public boolean contentEquals(StringBuffer sb) {
synchronized(sb) {
return contentEquals((CharSequence)sb);
}
}
equals()và contentEquals()là hai phương thức trong Stringlớp để so sánh hai stringsvà stringvới StringBuffer.
Các thông số của contentEquals()là StringBuffervà String(charSequence). equals()được sử dụng để so sánh hai stringsvà contentEquals()được sử dụng để so sánh nội dung của Stringvà StringBuffer.
Phương pháp contentEqualsvà equalslà
public boolean contentEquals(java.lang.StringBuffer);
public boolean contentEquals(java.lang.CharSequence);
public boolean equals(Object o)
Đây là một mã mô tả cả hai phương thức
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);
}
}
Đầu ra:
str1.equals(str2) - true
str1.equals(sb1) - false
str1.contentEquals(sb1) - true
str1.contentEquals(sb2) - false
str1.contentEquals(str2) - true
Chuỗi # bằng lấy đối tượng làm đối số và kiểm tra xem nó có phải là đối tượng của đối tượng Chuỗi hay không. Nếu đối tượng đối số là String Object thì nó so sánh nội dung theo từng ký tự. Nó trả về true trong trường hợp nội dung của cả hai đối tượng chuỗi là như nhau.
Chuỗi # contentEquals lấy giao diện CharSequence làm đối số. CharSequence có thể được thực hiện theo 2 cách - bằng cách sử dụng i) Lớp String hoặc (ii) AbstractStringBuilder (lớp cha của StringBuffer, StringBuilder)
Trong contentEquals () chiều dài được so sánh trước bất kỳ kiểm tra thể hiện đối tượng nào. Nếu độ dài là như nhau thì nó sẽ kiểm tra đối tượng có phải là đối tượng của AbstractStringBuilder hay không. Nếu đúng như vậy (ví dụ StringBuffer hoặc StringBuilder) thì nội dung được kiểm tra theo từng ký tự. Trong trường hợp đối số là một thể hiện của đối tượng String thì String # bằng được gọi từ String # contentEquals.
Vì vậy, trong ngắn hạn,
Chuỗi # bằng so sánh ký tự nội dung theo ký tự trong trường hợp đối số cũng là đối tượng Chuỗi. Và String # contentEquals so sánh nội dung trong trường hợp đối tượng đối số triển khai giao diện CharSequence.
Chuỗi # contentEquals chậm hơn trong trường hợp chúng ta so sánh hai nội dung chuỗi có cùng độ dài như Chuỗi # contentEquals gọi nội bộ Chuỗi # bằng với đối tượng Chuỗi.
Trong trường hợp chúng tôi cố gắng so sánh các đối tượng có độ dài nội dung khác nhau (giả sử "abc" với "abcd") thì String # contentEquals nhanh hơn String # bằng. Bởi vì độ dài được so sánh trước khi bất kỳ đối tượng kiểm tra.
Các contentEquals()kiểm tra phương pháp là nội dung là giống nhau giữa một String, StringBuffer, vv mà một số loại chuỗi char.
BTW, lý do lịch sử cho sự khác biệt là String ban đầu không có siêu lớp, vì vậy String.equals () lấy String làm đối số của nó. Khi CharSequence được giới thiệu là siêu lớp của Chuỗi, nó cần một phép kiểm tra đẳng thức của chính nó hoạt động trên tất cả các triển khai CharSequence và nó sẽ không va chạm với các chuỗi bằng () đã được sử dụng bởi String ... vì vậy chúng tôi đã nhận được CharSequence.contentEquals ( ), được kế thừa bởi String.
Nếu CharSequence đã có mặt trong Java 1.0, thì chúng tôi sẽ chỉ có CharSequence.equals () và String sẽ thực hiện điều đó.
Ah, niềm vui của ngôn ngữ phát triển ...
==(contentEquals) và===(bằng) trong javascript không?