2010-08-20 10 views
11

Trong ứng dụng Java của tôi, tôi cần so sánh phần tử của hai danh sách cho dù nó có tương tự hay không.Làm cho phần tử ArrayList không phân biệt chữ hoa chữ thường

Nói tóm lại giả sử tôi có hai danh sách tuyên bố như hình dưới đây

List<String> a = new ArrayList<String>(); 
    a.add("one"); 
    a.add("three"); 
    a.add("two"); 
Collections.sort(a); 


List<String> a1 = new ArrayList<String>(); 
    a1.add("ONE"); 
    a1.add("two"); 
    a1.add("THREE"); 
Collections.sort(a); 

Nếu tôi viết một điều kiện cho sự bình đẳng nó không thành công như một số các yếu tố danh sách là trong trường hợp khác nhau như

if(a.equals(a1)){ 
    System.out.println("equal"); 
} else{ 
    System.out.println("not equal"); 
} 

Nó sẽ kết quả hiển thị "Không bằng"

Vì vậy, hãy cho tôi biết cách tôi có thể làm cho phần tử danh sách không phân biệt chữ hoa chữ thường trong ngôn ngữ Java.

Thank và liên quan

+2

equalsIgnoreCase() - http://download-llnw.oracle.com/javase/6/docs/api/java/lang/String. html # equalsIgnoreCase (java.lang.String) –

+1

Giải pháp không phải là làm cho các phần tử * không phân biệt chữ hoa chữ thường (nghĩa là về mặt kỹ thuật có nghĩa là reimplementing String - không thể mở rộng nó vì nó là cuối cùng - với lớp bao bọc có các phương thức * bằng * và * compareTo * - không nhạy cảm, nhưng thay vì làm cho * so sánh * không phân biệt chữ hoa chữ thường. – user359996

Trả lời

20

Tại sao không sử dụng thay vào đó một SortedSet có bộ so sánh không phân biệt chữ hoa chữ thường? Với String.CASE_INSENSITIVE_ORDER so sánh

Mã của bạn được giảm xuống

Set<String> a = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); 
    a.add("one"); 
    a.add("three"); 
    a.add("two"); 


Set<String> a1 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); 
    a1.add("ONE"); 
    a1.add("two"); 
    a1.add("THREE"); 

Và điều kiện bình đẳng của bạn nên làm việc mà không cần bất kỳ vấn đề

EDIT sửa đổi theo ý kiến. Cảm ơn tất cả các bạn đã sửa tôi.

+1

(bạn phải sử dụng một hàm tạo TreeSet khác để sử dụng trình so sánh tùy chỉnh) –

+2

Bạn thực sự nên * sử dụng * Bộ so sánh 'mà bạn đã định nghĩa trong mã mẫu ;-) –

+3

Xem thêm Bộ so sánh tĩnh' String.CASE_INSENSITIVE_ORDER' trên lớp Chuỗi –

7

Bạn sẽ phải làm điều đó bằng tay:

public boolean equalsIgnoreCase(List<String> l1, List<String> l2) { 
    if (l1.size() != l2.size()) { 
    return false; 
    } 
    Iterator<String> i1=l1.iterator(); 
    Iterator<String> i2=l2.iterator(); 
    while(i1.hasNext()) { 
    if (!i1.next().equalsIgnoreCase(i2.next()) { 
     return false; 
    } 
    } 
    return true; 
} 
+0

oops, typo ngu ngốc, cảm ơn gizmo ;-) –

14

Bạn cần phải sử dụng

Collections.sort(a, String.CASE_INSENSITIVE_ORDER); 

để sắp xếp bỏ qua trường hợp, bạn có thể sử dụng equalsIgnoreCase phương thức trên Chuỗi để so sánh với các giá trị

Tất nhiên, bạn có thể tạo CaseIn riêng của mình lớp ensitiveList, chúng tôi có một CaseInsensitiveSet & CaseInsensitiveMap trong mã số của chúng tôi

+1

Đó không phải là một giải pháp hoàn chỉnh (không phải là bài viết của tôi dưới đây ;-)). –

+0

Như Joachim nói, điều này sẽ ** không ** làm cho 'a.equals (a1)' trả về true. –

+0

Có, tôi đã đăng một chút quá sớm, tôi đã chỉnh sửa câu trả lời gốc –

0

Bạn sẽ cần ghi đè phương thức equals() trong danh sách để nó thực hiện những gì bạn muốn. Hãy xem ArrayList.equals hiện tại() và điều chỉnh nó để so sánh với equalsIgnoreCase thay vì bằng().

+0

Hoặc bạn làm cho nó mất một so sánh như là một đối số constructor. Nhưng vấn đề là cả hai điều này vi phạm hợp đồng cho 'Bộ sưu tập' và điều này có thể khiến mọi thứ không hoạt động như mong đợi. –

6

Bạn cũng có thể quấn dây của bạn thành một lớp helper và thực hiện các bằng & so sánh phương pháp cho nó.

public class StringWrapper implements Comparable<StringWrapper> { 
    private String value; 

    StringWrapper(Strig value) { 
     this.value = value; 
    } 

    @Override boolean equals(Object o) { 
     returns String.CASE_INSENSITIVE_ORDER.equals(
      (StringWrapper) o).value 
      this.value); 
    } 

    @Override int compareTo(StringWrapper sw) { 
     returns String.CASE_INSENSITIVE_ORDER.compare(
      this.value 
      sw.value);   
    } 

    @Override String toString() { 
     return this.value; 
    } 

    @Override int hashCode() { 
     return this.value.toLowerCase.hashCode(); 
    } 
} 

And then : 

List<StringWrapper> a = new ArrayList<StringWrapper>(); 
    a.add(StringWrapper("one")); 
    a.add(StringWrapper("TWO")); 
    a.add(StringWrapper("three")); 
Collections.sort(a); 
+0

Bạn nên thực hiện 'Comparable ', và thay đổi phương thức 'compareTo (Object)' so sánh (StringWrapper) '. Bạn cũng nên thực hiện 'hashCode()', điều này có thể trở nên phức tạp. –

+0

(StringWrapper cần triển khai giao diện 'Comparable' - nếu không' Collections.sort' gây ra lỗi thời gian biên dịch) –

+0

, đây chắc chắn là cách để đi (+1) –

0

Cách viết lớp Wrapper vào Danh sách bạn đang sử dụng, điều này sẽ tránh được việc lưu trữ các phần tử không nhất quán.

public class CaseInsensitiveStringList extends ArrayList<String> { 

    @Override 
    public void add(final int index, final String element) { 
     super.add(index, element.toLowerCase()); 
    } 

    @Override 
    public boolean add(final String o) { 
     return super.add(o.toLowerCase()); 
    } 

    @Override 
    public boolean addAll(final Collection<? extends String> c) { 
     final ArrayList<String> temp = new ArrayList<String>(c.size()); 
     for (final String s : c) { 
      temp.add(s.toLowerCase()); 
     } 
     return super.addAll(temp); 
    } 

    @Override 
    public boolean addAll(final int index, final Collection<? extends String> c) { 
     final ArrayList<String> temp = new ArrayList<String>(c.size()); 
     for (final String s : c) { 
      temp.add(s.toLowerCase()); 
     } 
     return super.addAll(index, temp); 
    } 
} 
0

Để sắp xếp danh sách các Strings bỏ qua trường hợp

Arrays.sort(myArray, Collator.getInstance());