2012-06-30 70 views
94

Tôi muốn so sánh hai chuỗi cho sự bình đẳng trong Java, khi một hoặc cả hai có thể là null, vì vậy tôi không thể gọi đơn giản là .equals(). cách tốt nhất là gì?So sánh hai chuỗi trong Java với các giá trị null có thể

boolean compare(String str1, String str2) { 
    ... 
} 

Edit:

return ((str1 == str2) || (str1 != null && str1.equals(str2))); 
+0

bản sao có thể có của [Cách tốt hơn để so sánh các chuỗi có thể là null] (http://stackoverflow.com/questions/8336856/a-better-way-to-compare-strings-which-could-be-null) – jimr

Trả lời

118

Đây là những gì Java sử dụng nội bộ mã (trên compare phương pháp khác):

public static boolean compare(String str1, String str2) { 
    return (str1 == null ? str2 == null : str1.equals(str2)); 
} 
+3

Tại sao không chỉ thay đổi kiểu Chuỗi thành Đối tượng - làm cho nó trở nên chung chung hơn? Và sau đó nó cũng giống như những gì bạn sẽ nhận được nếu bạn chuyển sang Java 7. – Tom

+1

Lớp java nào chứa phương thức bạn đã cung cấp? –

+0

@VolodymyrLevytskyi Phương pháp 'so sánh' cụ thể này không có trong Java JDK. Nếu có, tôi sẽ đề nghị sử dụng nó. – Eric

2
boolean compare(String str1, String str2) { 
    if(str1==null || str2==null) { 
     //return false; if you assume null not equal to null 
     return str1==str2; 
    } 
    return str1.equals(str2); 
} 

này là những gì bạn mong muốn?

+4

Trường hợp này trả về 'false' nếu cả hai chuỗi là' null' có thể không phải là kết quả mong muốn. – JScoobyCed

1
boolean compare(String str1, String str2) { 
    if (str1 == null || str2 == null) 
     return str1 == str2; 

    return str1.equals(str2); 
} 
1
boolean compare(String str1, String str2) { 
    return (str1==null || str2==null) ? str1 == str2 : str1.equals(str2); 
} 
29

Đối với những trường hợp này nó sẽ là tốt hơn để sử dụng Apache CommonsStringUtils#equals, nó đã xử lý chuỗi null. Mẫu mã:

public boolean compare(String s1, String s2) { 
    return StringUtils.equals(s1, s2); 
} 

Nếu bạn không muốn thêm thư viện, chỉ cần sao chép source code của phương pháp StringUtils#equals và áp dụng nó khi bạn cần nó.

0

OK, vậy "giải pháp tốt nhất có thể" có nghĩa là gì?

Nếu bạn có nghĩa là dễ đọc nhất, thì tất cả các giải pháp có thể là tương đương với một lập trình Java có kinh nghiệm. Nhưng IMO dễ đọc nhất là

public boolean compareStringsOrNulls(String str1, String str2) { 
    // Implement it how you like 
} 

Nói cách khác, ẩn thực hiện bên trong một phương pháp đơn giản (lý tưởng) có thể được gạch chân.

(Bạn có thể cũng "out-nguồn" đến 3 thư viện tiện ích bên ... nếu bạn đã sử dụng nó trong codebase của bạn.)


Nếu bạn có ý nghĩa performant nhất, sau đó:

  1. giải pháp performant nhất phụ thuộc vào nền tảng và bối cảnh,
  2. một trong những vấn đề "bối cảnh" là tương đối (động) tần số xuất hiện của null lập luận,
  3. it có lẽ không quan trọng phiên bản nào nhanh hơn ... vì sự khác biệt có thể quá nhỏ để tạo sự khác biệt cho hiệu suất ứng dụng tổng thể và
  4. nếu nó quan trọng, cách duy nhất để tìm ra nhanh nhất TRÊN PLATFORM của bạn là thử cả hai phiên bản và đo sự khác biệt.
143

Vì Java 7 bạn có thể sử dụng phương pháp tĩnh Objects.equals(Object, Object) để thực hiện bằng kiểm tra trên hai đối tượng mà không quan tâm đến chúng là null.

Nếu cả hai đối tượng là null, nó sẽ trả về true, nếu một là null và khác không phải là nó sẽ trả lại false.Nếu không, nó sẽ trả về kết quả của việc gọi equals trên đối tượng đầu tiên với đối số thứ hai làm đối số.

+0

cách tiếp cận này sẽ ngăn chặn việc kiểm tra kiểu cho đến khi chạy chương trình. hai hậu quả: nó sẽ chậm hơn trong thời gian chạy và IDE sẽ không cho bạn biết nếu bạn vô tình cố gắng so sánh các loại khác nhau. – averasko

+3

@averasko Khi bạn sử dụng 'Object.equals (Object)' không có kiểm tra kiểu thời gian biên dịch. 'Objects.equals (Object, Object)' hoạt động rất giống với bình thường 'equals', và suy luận lại/kiểm tra bằng IDE, những quy tắc đó là heuristics cũng được hỗ trợ cho' Objects.equals (Object, Object) ' (ví dụ: IntelliJ IDEA 2016.2 có cùng một kiểm tra cho cả hai bình thường và một từ các đối tượng). –

+0

Tôi thích cách tiếp cận này. Không cần phải bao gồm một số thư viện ApacheCommons cho những thứ những ngày này. –

20

Đối với những người trên android, người không thể sử dụng API 19 của Objects.equals (str1, str2), có là thế này:

android.text.TextUtils.equals(str1, str2); 

Nó là an toàn null. Nó hiếm khi phải sử dụng phương thức string.equals() đắt tiền hơn vì các chuỗi giống hệt nhau trên android hầu như luôn so sánh đúng với toán tử "==" nhờ Android's String Pooling và kiểm tra độ dài là cách nhanh nhất để lọc ra những sự không phù hợp nhất.

Source Code:

/** 
* Returns true if a and b are equal, including if they are both null. 
* <p><i>Note: In platform versions 1.1 and earlier, this method only worked well if 
* both the arguments were instances of String.</i></p> 
* @param a first CharSequence to check 
* @param b second CharSequence to check 
* @return true if a and b are equal 
*/ 
public static boolean equals(CharSequence a, CharSequence b) { 
    if (a == b) return true; 
    int length; 
    if (a != null && b != null && (length = a.length()) == b.length()) { 
     if (a instanceof String && b instanceof String) { 
      return a.equals(b); 
     } else { 
      for (int i = 0; i < length; i++) { 
       if (a.charAt(i) != b.charAt(i)) return false; 
      } 
      return true; 
     } 
    } 
    return false; 
} 
0

Bạn có thể sử dụng java.util.Objects như sau.

public static boolean compare(String str1, String str2) { 
    return Objects.equals(str1, str2); 
} 
4

Kể từ phiên bản 3.5 Apache Commons StringUtils có các phương pháp sau:

static int compare(String str1, String str2) 
static int compare(String str1, String str2, boolean nullIsLess) 
static int compareIgnoreCase(String str1, String str2) 
static int compareIgnoreCase(String str1, String str2, boolean nullIsLess) 

Những cung cấp vô an toàn so sánh String.

Các vấn đề liên quan