Sự khác biệt giữa String#equals
phương pháp và String#contentEquals
phương pháp là gì?
Sự khác biệt giữa String#equals
phương pháp và String#contentEquals
phươ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 CharSequence
trong đó bao gồm ao String
, StringBuilder
, StringBuffer
, CharBuffer
vv
==
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ề equals
việ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 equals
phươ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à:
equals
phươ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 CharSequence
và 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 StringBuffer
và StringBuilder
mộ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#contentEquals
một phương thức lấy StringBuilder
và phương thức khác CharSequence
.
Sự khác biệt giữa chúng,
String#contentEquals
sẽ ném NPE nếu đối số được cung cấp null
nhưng String#equals
sẽ trả vềfalse
String#equals
chỉ so sánh nội dung khi đối số được cung cấp instance of String
nếu không nó sẽ trả về false
trong tất cả các trường hợp khác nhưng mặt khác String#contentEquals
kiể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#contentEquals
trả về kết quả sai hoặc kết quả bạn muốn bằng cách ghi đè equals
phươ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à s
chứa bất kỳ string
ký 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#contentEquals
sẽ chậm hơn String#Equals
trong trường hợp khi đối số được cung cấp là instance of String
và độ dài của cả hai String
là 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#contentEquals
sẽ có hiệu suất tốt hơn String#Equals
trong 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#contentEquals
của một String
đối tượng cũng sẽ so sánh với StringBuilder
nội dung và cung cấp kết quả phù hợp trong khi String#Equals
sẽ trả vềfalse
String
equals(Object o)
phương pháp lớp không chỉ String
so sánh. Nhưng contentEquals(CharSequence cs)
kiểm tra cho các lớp học kéo dài AbstractStringBuilder
tức StringBuffer
, StringBuilder
và String
lớ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à false
bởi vì builder
không phải là loại String
để equals()
trở về false
nhưng contentEquals()
kiểm tra về nội dung của tất cả các loại như StringBuilder
, StringBuffer
, String
và như nội dung là giống nhau vì thế true
.
contentEquals
sẽ ném NullPointerException
nếu đối số được cung cấp là null
như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 String
lớp để so sánh hai strings
và string
với StringBuffer
.
Các thông số của contentEquals()
là StringBuffer
và String(charSequence)
. equals()
được sử dụng để so sánh hai strings
và contentEquals()
được sử dụng để so sánh nội dung của String
và StringBuffer
.
Phương pháp contentEquals
và equals
là
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?