Is there an option to ignore case with .contains()
method?
I have an ArrayList
of DVD object. Each DVD object has a few elements, one of them is a title. And I have a method that searches for a specific title. It works, but I'd like it to be case insensitive.
This probably isn't the best way for your particular problem, but you can use the String.matches(String regex)
method or the matcher equivalent. We just need to construct a regular expression from your prospective title. Here it gets complex.
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;
}
But this is inefficient, and it's being done purely in Java. You would do better to try one of these techniques:
Collator
and CollationKey
classes.boolean matches(String fragment)
. Have the DVD tell you what it matches.title
column of the DVD
table that way. Use JDBC or Hibernate or JPA or Spring Data, whichever you choose.Apache Lucene
and possibly Apache Solr
.If you can wait until Java 8, use lambda expressions. You can avoid the Pattern and Matcher class that I used above by building the regex this way:
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);
}
But this compiles the pattern too many times. What about lower-casing everything?
if (dvd.getTitle().toLowerCase().contains(titleFragment.toLowerCase()))
Congratulations; you've just discovered the Turkish problem. Unless you state the locale in toLowerCase
, Java finds the current locale. And the lower-casing is slow because it has to take into account the Turkish dotless i and dotted I. At least you have no patterns and no matchers.
If you are looking for contains & not equals then i would propose below solution. Only drawback is if your searchItem in below solution is "DE" then also it would match
List<String> list = new ArrayList<>();
public static final String[] LIST_OF_ELEMENTS = { "ABC", "DEF","GHI" };
String searchItem= "def";
if(String.join(",", LIST_OF_ELEMENTS).contains(searchItem.toUpperCase())) {
System.out.println("found element");
break;
}
With a null check on the dvdList
and your searchString
if (!StringUtils.isEmpty(searchString)) {
return Optional.ofNullable(dvdList)
.map(Collection::stream)
.orElse(Stream.empty())
.anyMatch(dvd >searchString.equalsIgnoreCase(dvd.getTitle()));
}
You can't guarantee that you're always going to get String
objects back, or that the object you're working with in the List
implements a way to ignore case.
If you do want to compare String
s in a collection to something independent of case, you'd want to iterate over the collection and compare them without case.
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
}
}
private boolean containsIgnoreCase(List<String> list, String soughtFor) {
for (String current : list) {
if (current.equalsIgnoreCase(soughtFor)) {
return true;
}
}
return false;
}
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;
}
If you're using Java 8
List<String> list = new ArrayList<>();
boolean containsSearchStr = list.stream().anyMatch("search_value"::equalsIgnoreCase);
For Java 8, You can have one more solution like below
List<String> list = new ArrayList<>();
String searchTerm = "dvd";
if(String.join(",", list).toLowerCase().contains(searchTerm)) {
System.out.println("Element Present!");
}
In Java 8 you can use the Stream interface:
return dvdList.stream().anyMatch(d -> d.getTitle().equalsIgnoreCase("SomeTitle"));
The intuitive solution to transform both operands to lower case (or upper case) has the effect of instantiating an extra String object for each item which is not efficient for large collections. Also, regular expressions are an order of magnitude slower than simple characters comparison.
String.regionMatches()
allows to compare two String regions in a case-insensitive way. Using it, it's possible to write an efficient version of a case-insensitive "contains" method. The following method is what I use; it's based on code from 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;
}
I know I'm a little late to the party but in Kotlin you can easily use:
fun Collection<String>.containsIgnoreCase(item: String) = any {
it.equals(item, ignoreCase = true)
}
val list = listOf("Banana")
println(list.contains("banana"))
println(list.containsIgnoreCase("BaNaNa"))
You can apply little trick over this.
Change all the string to same case: either upper or lower case
For C# Code:
List searchResults = sl.FindAll(s => s.ToUpper().Contains(seachKeyword.ToUpper()));
For Java Code:
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);
}
}
}
}
Source: Stackoverflow.com