2010-02-08 11 views
82

Tôi tạo ra một chương trình Java để so sánh hai chuỗi:Làm cách nào để làm cho trường hợp so sánh chuỗi của tôi không nhạy cảm?

String s1 = "Hello"; 
String s2 = "hello"; 

if (s1.equals(s2)) { 
    System.out.println("hai"); 
} else { 
    System.out.println("welcome"); 
} 

Nó hiển thị "chào đón". Tôi hiểu đó là trường hợp nhạy cảm. Nhưng vấn đề của tôi là tôi muốn so sánh hai chuỗi mà không có sự nhạy cảm chữ hoa. I E. Tôi mong đợi đầu ra là hai.

+3

Nếu bạn biết điều đó là trường hợp nhạy cảm, bạn có thể chuyển đổi tất cả thành chữ thường hoặc chữ hoa trước khi so sánh. – fastcodejava

+0

nếu bạn sử dụng 's1.equalsIgnoreCase (s2)' bạn có thể không làm điều đó ở mọi nơi cần được thực hiện. Tôi khuyên bạn nên tìm chuỗi nơi xuất phát - một tệp hoặc cơ sở dữ liệu hoặc đầu vào của người dùng có lẽ - và chuyển đổi thành chữ hoa (hoặc chữ thường) và tiếp tục sử dụng .equals for the compare. – H2ONaCl

+0

Không chuyển đổi thành chữ thường/chữ hoa (như gợi ý của các chú thích ở trên), sử dụng phương thức 'equalsIgnoreCase' được chấp nhận. Tìm hiểu về vấn đề Thổ Nhĩ Kỳ I và các vấn đề Unicode tương tự cho lý do cơ bản. –

Trả lời

140
  • Điều tốt nhất sẽ được sử dụng s1.equalsIgnoreCase(s2): (xem javadoc)
  • Bạn cũng có thể chuyển đổi chúng cả chữ hoa/thấp hơn và sử dụng s1.equals(s2)
+34

Chỉ cần lưu ý rằng hai giải pháp không nhất thiết phải giống nhau cho tất cả các ngôn ngữ. Chuỗi # equalsIgnoreCase không sử dụng quy tắc vỏ địa phương cụ thể, trong khi String # toLowerCase và #toUpperCase làm. – jarnbjo

+0

@jarnbjo Bạn có thể đưa ra ví dụ cho sự khác biệt đó không? – towi

+14

Quy tắc trường hợp cụ thể của địa phương ít nhất được triển khai cho tiếng Thổ Nhĩ Kỳ và tiếng Đức. Thổ Nhĩ Kỳ đối xử với tôi có và không có dấu chấm như hai chữ cái khác nhau, tạo ra các cặp chữ hoa/chữ thường i/i và ıI trong khi các ngôn ngữ khác coi iI là một cặp và không sử dụng chữ cái ı và İ. Trong tiếng Đức, trường hợp thấp hơn ß được viết hoa là "SS". – jarnbjo

16

Bạn phải sử dụng các phương pháp compareToIgnoreCase của đối tượng String.

int compareValue = str1.compareToIgnoreCase(str2); 

if (compareValue == 0) nó có nghĩa str1 bằng str2.

+1

không biết phương pháp này cũng có sẵn. cảm ơn! –

2

Lưu ý rằng bạn có thể muốn thực hiện kiểm tra null trên chúng cũng như trước khi thực hiện .equals hoặc .equalsIgnoreCase.

Đối tượng chuỗi rỗng không thể gọi phương thức bằng.

ví dụ:

public boolean areStringsSame(String str1, String str2) 
{ 
    if (str1 == null && str2 == null) 
     return true; 
    if (str1 == null || str2 == null) 
     return false; 

    return str1.equalsIgnoreCase(str2); 
} 
+1

Lưu ý: hai câu lệnh thứ hai có thể được kết hợp để tạo ra kết quả tương tự như sau: 'if (str1 == null || str2 == null) trả về false;'. – LuckyMe

+0

Mã được sửa đổi phải sạch hơn như bình luận ở trên - là ngày dài :) – VeenarM

+1

Bạn cũng có thể thay đổi dòng đầu tiên thành 'if (str1 == str2) trả về true;' cả hai đều phục vụ cho các giá trị rỗng và các phím tắt trong trường hợp hai tham chiếu chuỗi tham chiếu đến cùng một đối tượng chuỗi. – Barney

3

Trong Java API mặc định bạn có:

String.CASE_INSENSITIVE_ORDER 

Vì vậy, bạn không cần phải viết lại một so sánh nếu bạn đã sử dụng chuỗi với các cấu trúc dữ liệu được sắp xếp.

String s = "some text here"; 
s.equalsIgnoreCase("Some text here"); 

Là những gì bạn muốn kiểm tra bình đẳng thuần túy trong mã của riêng bạn.

Chỉ cần cung cấp thêm thông tin về bất kỳ điều gì liên quan đến sự bình đẳng của chuỗi trong Java. HashCode() chức năng của lớp java.lang.String "là trường hợp nhạy cảm":

public int hashCode() { 
    int h = hash; 
    if (h == 0 && value.length > 0) { 
     char val[] = value; 

     for (int i = 0; i < value.length; i++) { 
      h = 31 * h + val[i]; 
     } 
     hash = h; 
    } 
    return h; 
} 

Vì vậy, nếu bạn muốn sử dụng một Hashtable/HashMap với Strings như chìa khóa, và có các phím như "SomeKey", " SOMEKEY "và" somekey "được xem như nhau, sau đó bạn sẽ phải quấn chuỗi của bạn trong một lớp khác (bạn không thể mở rộng chuỗi vì nó là một lớp cuối cùng).Ví dụ:

private static class HashWrap { 
    private final String value; 
    private final int hash; 

    public String get() { 
     return value; 
    } 

    private HashWrap(String value) { 
     this.value = value; 
     String lc = value.toLowerCase(); 
     this.hash = lc.hashCode(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o instanceof HashWrap) { 
      HashWrap that = (HashWrap) o; 
      return value.equalsIgnoreCase(that.value); 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public int hashCode() { 
     return this.hash; 
    } 
} 

và sau đó sử dụng nó như vậy:

HashMap<HashWrap, Object> map = new HashMap<HashWrap, Object>(); 
-5
public boolean newEquals(String str1, String str2) 
{ 
    int len = str1.length(); 
int len1 = str2.length(); 
if(len==len1) 
{ 
    for(int i=0,j=0;i<str1.length();i++,j++) 
    { 
     if(str1.charAt(i)!=str2.charAt(j)) 
     return false; 
    }`enter code here` 
} 
return true; 
} 
+2

Câu trả lời không rõ ràng và khó hiểu –

+0

và cũng không chính xác –

8
import java.lang.String; //contains equalsIgnoreCase() 
/* 
* 
*/ 
String s1 = "Hello"; 
String s2 = "hello"; 

if (s1.equalsIgnoreCase(s2)) { 
System.out.println("hai"); 
} else { 
System.out.println("welcome"); 
} 

Bây giờ nó sẽ ra: hai

19

String.equalsIgnoreCase là sự lựa chọn thiết thực nhất cho đựng pin- ngây thơ so sánh chuỗi không nhạy cảm. Tuy nhiên, bạn nên biết rằng phương pháp này không thực hiện quá trình phân tích và phân tích chữ hoa chữ thường và do đó, không thể thực hiện khớp không khớp như được quy định trong tiêu chuẩn Unicode. Trên thực tế, các API JDK không cung cấp quyền truy cập thông tin về dữ liệu ký tự gấp chữ hoa, do đó, công việc này được ủy quyền tốt nhất cho thư viện của bên thứ ba đã được thử nghiệm và thử nghiệm.

Đó thư viện là ICU, và đây là cách người ta có thể thực hiện một tiện ích cho case-insensitive so sánh chuỗi:

import com.ibm.icu.text.Normalizer2; 

// ... 

public static boolean equalsIgnoreCase(CharSequence s, CharSequence t) { 
    Normalizer2 normalizer = Normalizer2.getNFKCCasefoldInstance(); 
    return normalizer.normalize(s).equals(normalizer.normalize(t)); 
} 
String brook = "flu\u0308ßchen"; 
    String BROOK = "FLÜSSCHEN"; 

    assert equalsIgnoreCase(brook, BROOK); 

so Naive với String.equalsIgnoreCase, hoặc String.equals trên dây thượng hoặc lowercased sẽ thất bại ngay cả thử nghiệm đơn giản này.

(Do lưu ý rằng mặc dù các trường hợp được xác định trước gấp hương vị getNFKCCasefoldInstance là miền địa phương độc lập;. Cho miền địa phương Thổ Nhĩ Kỳ nhiều hơn một chút công việc liên quan đến UCharacter.foldCase có thể cần thiết)

-1

Để có nullsafe, bạn có thể sử dụng

org.apache.commons.lang.StringUtils.equalsIgnoreCase(String, String) 

hoặc

org.apache.commons.lang3.StringUtils.equalsIgnoreCase(CharSequence, CharSequence)