2013-04-05 31 views
20

Có tùy chọn bỏ qua trường hợp với phương thức .contains không?Tùy chọn bỏ qua trường hợp bằng phương thức .contains?

Tôi có một ArrayList đối tượng DVD. Mỗi đối tượng DVD có một vài phần tử, một trong số đó là một tiêu đề. Và tôi có một phương pháp tìm kiếm một tiêu đề cụ thể. Nó hoạt động, nhưng tôi muốn nó không phân biệt chữ hoa chữ thường.

+0

Không, không có. Nhưng nếu bạn giải thích những gì bạn đang cố gắng để làm, chúng tôi có thể có thể đề xuất một cách tiếp cận thay thế mà sẽ làm những gì bạn cần. – DaoWen

+0

Để thực hiện khớp không phân biệt dạng chữ trong Java, bạn có thể sử dụng 'String.matches' với cụm từ thông dụng'. * (? I: abcd). * '. Thay thế 'abcd' bằng chuỗi của bạn. –

+1

có thể trùng lặp của [Có chứa Phương thức trong java.lang.String Phân biệt chữ hoa chữ thường không?] (Http://stackoverflow.com/questions/86780/is-the-contains-method-in-java-lang-string-case -sensitive) –

Trả lời

20

Tôi đoán bạn có nghĩa là bỏ qua trường hợp khi tìm kiếm trong chuỗi?

Tôi không biết, nhưng bạn có thể thử chuyển đổi chuỗi để tìm kiếm thành chữ thường hoặc chữ hoa, sau đó tìm kiếm.

// s is the String to search into, and seq the sequence you are searching for. 
bool doesContain = s.toLowerCase().contains(seq); 

Edit: Như Ryan Schipper gợi ý, bạn cũng có thể (và có lẽ sẽ tốt hơn off) làm seq.toLowerCase(), tùy thuộc vào tình hình của bạn.

+4

có thể muốn 'seq.toLowerCase()' trong đó cũng có;) –

+1

Dangit, hiển nhiên .... Đó là một ngày dài. Cảm ơn! – trama

+1

Câu trả lời này là sai. Xem http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug để giải thích lý do tại sao bạn không thể đơn giản gọi 'toLowerCase()' để so sánh phân biệt dạng chữ. – Gili

2

Bạn không thể đảm bảo rằng bạn sẽ luôn nhận được String đối tượng trở lại hoặc đối tượng bạn đang làm việc trong số List thực hiện cách bỏ qua trường hợp.

Nếu bạn muốn so sánh String trong bộ sưu tập với một điều gì đó độc lập với trường hợp, bạn muốn lặp lại bộ sưu tập và so sánh chúng mà không có trường hợp.

String word = "Some word"; 
List<String> aList = new ArrayList<>(); // presume that the list is populated 

for(String item : aList) { 
    if(word.equalsIgnoreCase(item)) { 
     // operation upon successful match 
    } 
} 
+0

Nếu anh ta sử dụng 'List ', anh ta sẽ biết. –

+0

... tại thời điểm đó, bạn có thể sử dụng phương thức 'String' trên phần tử riêng lẻ trong' Danh sách', nhưng không phải trực tiếp trên 'Danh sách'. – Makoto

4

Đây có lẽ không phải là cách tốt nhất cho vấn đề cụ thể của bạn, nhưng bạn có thể sử dụng phương pháp String.matches(String regex) hoặc tương đương với đối sánh. Chúng tôi chỉ cần xây dựng cụm từ thông dụng từ tiêu đề tiềm năng của bạn. Ở đây nó trở nên phức tạp.

List<DVD> matchingDvds(String titleFragment) { 
    String escapedFragment = Pattern.quote(titleFragment); 
    // The pattern may have contained an asterisk, dollar sign, etc. 
    // For example, M*A*S*H, directed by Robert Altman. 
    Pattern pat = Pattern.compile(escapedFragment, Pattern.CASE_INSENSITIVE); 
    List<DVD> foundDvds = new ArrayList<>(); 
    for (DVD dvd: catalog) { 
     Matcher m = pat.matcher(dvd.getTitle()); 
     if (m.find()) { 
      foundDvds.add(dvd); 
     } 
    } 
    return foundDvds; 
} 

Nhưng điều này không hiệu quả và được thực hiện hoàn toàn bằng Java. Bạn sẽ làm tốt hơn để thử một trong các kỹ thuật sau:

  1. Tìm hiểu các lớp CollatorCollationKey.
  2. Nếu bạn không có lựa chọn nào khác ngoài việc ở lại thế giới Java, hãy thêm phương thức vào DVD, boolean matches(String fragment). Có đĩa DVD cho bạn biết những gì nó phù hợp.
  3. Sử dụng cơ sở dữ liệu. Nếu nó hỗ trợ collations không phân biệt dạng chữ, hãy khai báo cột title của bảng DVD theo cách đó. Sử dụng JDBC hoặc Hibernate hoặc JPA hoặc Spring Data, tùy theo bạn chọn.
  4. Nếu cơ sở dữ liệu hỗ trợ tìm kiếm văn bản nâng cao, như Oracle, hãy sử dụng nó.
  5. Quay lại thế giới Java, sử dụng Apache Lucene và có thể là Apache Solr.
  6. Sử dụng ngôn ngữ được điều chỉnh cho các kết quả khớp không phân biệt chữ hoa chữ thường.

Nếu bạn có thể đợi cho đến khi Java 8, sử dụng biểu thức lambda. Bạn có thể tránh lớp Pattern và Matcher mà tôi sử dụng ở trên bằng cách xây dựng các regex theo cách này:

String escapedFragment = Pattern.quote(titleFragment); 
    String fragmentAnywhereInString = ".*" + escapedFragment + ".*"; 
    String caseInsensitiveFragment = "(?i)" + fragmentAnywhereInString; 
    // and in the loop, use: 
    if(dvd.getTitle().matches(caseInsensitiveFragment)) { 
     foundDvds.add(dvd); 
    } 

Nhưng điều này biên dịch mô hình quá nhiều lần. Điều gì về thấp hơn vỏ bọc tất cả mọi thứ?

if (dvd.getTitle().toLowerCase().contains(titleFragment.toLowerCase())) 

Xin chúc mừng; bạn vừa phát hiện ra vấn đề của Thổ Nhĩ Kỳ. Trừ khi bạn nêu ngôn ngữ trong toLowerCase, Java sẽ tìm thấy ngôn ngữ hiện tại.Và vỏ bọc thấp hơn là chậm bởi vì nó phải tính đến dấu chấm tròn của người Thổ Nhĩ Kỳ và chấm đen. Ít nhất bạn không có hoa văn và không phù hợp.

0
private List<String> FindString(String stringToLookFor, List<String> arrayToSearchIn) 
{ 
    List<String> ReceptacleOfWordsFound = new ArrayList<String>(); 

    if(!arrayToSearchIn.isEmpty()) 
    { 
     for(String lCurrentString : arrayToSearchIn) 
     { 
      if(lCurrentString.toUpperCase().contains(stringToLookFor.toUpperCase()) 
       ReceptacleOfWordsFound.add(lCurrentString); 
     } 
    } 
    return ReceptacleOfWordsFound; 
} 
7
private boolean containsIgnoreCase(List<String> list, String soughtFor) { 
    for (String current : list) { 
     if (current.equalsIgnoreCase(soughtFor)) { 
      return true; 
     } 
    } 
    return false; 
} 
+1

Điều này tương tự như câu trả lời để thực hiện tương tự với ArrayLists http: // stackoverflow.com/a/8751546/1815624 – CrandellWS

2

Giải pháp trực quan để chuyển đổi cả hai toán hạng để giảm trường hợp (hoặc chữ in hoa) có tác dụng instantiating thêm một đối tượng String cho từng hạng mục mà không phải là hiệu quả cho các bộ sưu tập lớn. Ngoài ra, biểu thức chính quy là thứ tự độ lớn chậm hơn so với so sánh các ký tự đơn giản.

String.regionMatches() cho phép so sánh hai vùng Chuỗi theo cách phân biệt chữ hoa chữ thường. Sử dụng nó, nó có thể viết một phiên bản hiệu quả của một phương pháp "chứa" không phân biệt chữ hoa chữ thường. Phương pháp sau đây là những gì tôi sử dụng; nó dựa trên mã từ Apache commons-lang:

public static boolean containsIgnoreCase(final String str, final String searchStr) { 
    if (str == null || searchStr == null) { 
     return false; 
    } 
    final int len = searchStr.length(); 
    final int max = str.length() - len; 
    for (int i = 0; i <= max; i++) { 
     if (str.regionMatches(true, i, searchStr, 0, len)) { 
      return true; 
     } 
    } 
    return false; 
} 
-1

Bạn có thể áp dụng một mẹo nhỏ.
Thay đổi tất cả các chuỗi để cùng trường hợp: hoặc trên hoặc chữ thường
Đối với C# Code:

Danh sách searchresults = sl.FindAll (s =>s.ToUpper () .Contains (seachKeyword.ToUpper()));

Đối với Mã Java:

import java.util.*; 

class Test 
{ 
    public static void main(String[] args) 
    { 
     String itemCheck="check"; 
     ArrayList<String> listItem =new ArrayList<String>(); 
     listItem.add("Check"); 
     listItem.add("check"); 
     listItem.add("CHeck"); 
     listItem.add("Make"); 
     listItem.add("CHecK"); 
     for(String item :listItem) 
     { 
      if(item.toUpperCase().equals(itemCheck.toUpperCase())) 
      { 
       System.out.println(item); 
      } 
     } 

    } 

} 
+1

Đây là câu hỏi về cách thực hiện trong Java, không phải trong C#. –

+0

Ok. Cùng một thủ thuật cũng có thể được áp dụng cho java. Bây giờ, tôi cũng đã thêm mã java. @PeterNeyens – Dipitak

16

Nếu bạn đang sử dụng Java 8

List<String> list = new ArrayList<>(); 

boolean containsSearchStr = list.stream().anyMatch("search_value"::equalsIgnoreCase); 
1

Trong Java 8 bạn có thể sử dụng giao diện Suối:

return dvdList.stream().anyMatch(d -> d.getTitle().equalsIgnoreCase("SomeTitle")); 
0

Đối với Java 8, Bạn có thể có thêm một giải pháp như bên dưới

List<String> list = new ArrayList<>(); 
String searchTerm = "dvd"; 

if(String.join(",", list).toLowerCase().contains(searchTerm)) { 
    System.out.println("Element Present!"); 
} 
Các vấn đề liên quan