ArrayList contains case sensitivity

前端 未结 19 1759
故里飘歌
故里飘歌 2020-11-27 17:14

I am currently using the contains method belonging to the ArrayList class for making a search. Is there a way to make this search case insensitive in java? I found that in C

相关标签:
19条回答
  • 2020-11-27 18:05

    ArrayList's contains() method checks equality by calling equals() method on the object you provide (NOT the objects in the array). Therefore, a slightly hackish way is to create a wrapper class around the String object, like this:

    class InsensitiveStringComparable {
        private final String val;
    
        public InsensitiveStringComparable(String val) {
            this.val = val;
        }
    
        @Override
        public boolean equals(Object x) {
            if (x == this)
                return true;
            else if (x == null)
                return false;
            else if (x instanceof InsensitiveStringComparable)
                return ((InsensitiveStringComparable) x).val.equalsIgnoreCase(val);
            else if (x instanceof String)
                /* Asymmetric equals condition */
                return val.equalsIgnoreCase((String) x);
            else
                return false;
        }
    
        @Override
        public int hashCode() {
            return val.toUpperCase().hashCode();
        }
    }
    

    Then you can use it to perform your test. Example "manual" test case:

    public class Test {
        public static void main(String[] args) {
            ArrayList<Object> a = new ArrayList<Object>();
            a.add("test");
            System.out.println(a.contains(new InsensitiveStringComparable("TEST")));
            System.out.println(a.contains(new InsensitiveStringComparable("tEsT")));
            System.out.println(a.contains(new InsensitiveStringComparable("different")));
        }
    }
    
    0 讨论(0)
  • 2020-11-27 18:07

    There's no need to for the additional function, the desired results can be achieved by casting the compared strings to either uppercase or lowercase

    (I know this has been suggested in the comments, but not thoroughly provided as an answer)

    Ex: Ignores case while filtering the contents of a JList based on the input provided from a JTextField:

    private ArrayList<String> getFilteredUsers(String filter, ArrayList<User> users) {
        ArrayList<String> filterUsers = new ArrayList<>();
        users.stream().filter((user) -> (user.getUsername().toUpperCase().contains(filter.toUpperCase()))).forEach((user)-> {
            filterUsers.add(user.getUsername());
        });
        this.userList.setListData(filterUsers.toArray());
        return filterUsers;
        /** 
         *  I see the redundancy in returning the object... so even though,
         *  it is passed by reference you could return type void; but because
         *  it's being passed by reference, it's a relatively inexpensive
         *  operation, so providing convenient access with redundancy is just a 
         *  courtesy, much like putting the seat back down. Then, the next
         *  developer with the unlucky assignment of using your code doesn't 
         *  get the proverbially dreaded "wet" seat.
         */
    }
    
    0 讨论(0)
  • 2020-11-27 18:08

    Assuming you have an ArrayList<String>

    About the only way I can think of to do this would be to create a very light wrapper class around a String and override equals and hashcode to ignore case, leveraging equalsIgnoreCase() where possible. Then you would have an ArrayList<YourString>. It's kinda an ugly idea though.

    0 讨论(0)
  • 2020-11-27 18:08

    If you don't want to create a new function, you can try this method:

    List<String> myList = new ArrayList<String>(); //The list you're checking
    String wordToFind = "Test"; //or scan.nextLine() or whatever you're checking
    
    //If your list has mix of uppercase and lowercase letters letters create a copy...
    List<String> copyList = new ArrayList<String>();
    for(String copyWord : myList){
       copyList.add(copyWord.toLowerCase());
    }
    
    for(String myWord : copyList){
       if(copyList.contains(wordToFind.toLowerCase()){
          //do something
       }
    }
    
    0 讨论(0)
  • 2020-11-27 18:09

    You can use IterableUtils and Predicate from collections4 (apache).

    List<String> pformats= Arrays.asList("Test","tEst2","tEsT3","TST4");
    
    Predicate<String> predicate  = (s) -> StringUtils.equalsIgnoreCase(s, "TEST");
    if(IterableUtils.matchesAny(pformats, predicate)) {
        // do stuff
    }
    

    IterableUtils(collections4): org.apache.commons.collections4.IterableUtils.html

    0 讨论(0)
  • 2020-11-27 18:10

    In Java8, using anyMatch

    List<String> list = Arrays.asList("XYZ", "ABC");
    String matchingText = "xYz";
    
    boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);
    
    0 讨论(0)
提交回复
热议问题