ProgramingTip

ArrayList에는 대소 문자 구분이 포함됩니다.

bestdevel 2020. 11. 19. 21:51
반응형

ArrayList에는 대소 문자 구분이 포함됩니다.


현재 검색을 위해 ArrayList 클래스에 존재하는 메서드를 사용하고 있습니다. 이 검색 대소 문자를 Java에서 구분하지 않는 방법이 있습니까? C #에서는 서수를 사용할 수 없습니다. Java에 발송하는 것이 아니면 수행하는 다른 방법이 있습니까? 감사합니다.


다른 ArrayList를 사용하는 것과 똑같이 사용할 수 있습니다. 이 목록을 다른 코드로 많은 수 있고 외부 코드는 클래스가 없습니다.

public class CustomStringList3 extends ArrayList<String> {
    @Override
    public boolean contains(Object o) {
        String paramStr = (String)o;
        for (String s : this) {
            if (paramStr.equalsIgnoreCase(s)) return true;
        }
        return false;
    }
}

Java8에서 anyMatch 사용

List<String> list = Arrays.asList("XYZ", "ABC");
String matchingText = "xYz";

boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);

Java 8을 사용하는 경우 다음을 시도하십시오.

List<String> list = ...;
String searchStr = ...;
boolean containsSearchStr = list.stream().filter(s -> s.equalsIgnoreCase(searchStr)).findFirst().isPresent();

전통적으로, 당신은 자신의 로직을 개발하여 . 아래에 여러 가지 방법이있을 수 있습니다.ArrayList

public boolean containsCaseInsensitive(String strToCompare, ArrayList<String>list)
{
    for(String str:list)
    {
        if(str.equalsIgnoreCase(strToCompare))
        {
            return(true);
        }
    }
    return(false);
}

대소 문자를 구분하지 않는 비교기로, SortedSet과 같은 직접 사용하는 방법을 사용하면 안되는 이유는 무엇입니까?

Set<String> a = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

a.add("A");
a.add("B");
a.add("C");


Set<String> b = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

b.add("a");
b.add("b");
b.add("c");

System.out.println(b.equals(a));

true이 특정 상황에서 두 개의 다른 세트를 무시하고 반환 하면 문제없이 작동합니다.


Java API를 살펴보면 많이 에 대한 메소드가 없습니다.

하지만 두 가지를 할 수 있습니다.

  1. ArrayList 객체의 equals 메소드를 자신의 것 또는 equalsIgnoreCase (str)로 재정의하십시오.
  2. ArrayList 엔터티를 반복해야하는 자신만의 메서드를 작성하고 수동 검사를 수행합니다.

    ArrayList<String> list = new ArrayList<String>();
    ...
    containsIgnoreCase("a", list);
    
    public boolean containsIgnoreCase(String str, ArrayList<String> list){
        for(String i : list){
            if(i.equalsIgnoreCase(str))
                return true;
        }
        return false;
    }
    

당신이 가지고있는 가정 ArrayList<String>

이 작업을 수행하는 유일한 방법은 문자열 주위에 매우 가벼운 래퍼 클래스를 만들고 대소 문자를 무시할 것 및 해시 코드를 재정의하는 것 equalsIgnoreCase()입니다. 그러면 ArrayList<YourString>. 그래도 추한 생각입니다.


collections4 (apache)에서 IterableUtils 및 Predicate를 사용할 수 있습니다.

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


contains방법은 반품에 equals상품 방법을 기반으로 ArrayList합니다. 대소 equals문자를 구분하지 않는 비교를 사용하는 것을 사용 하면 가능합니다 .

예를 들어 다음과 같은 클래스를 사용할 수 있습니다 (코드에 여전히 일부 오타가 있음).

public class CaseInsensitiveString{
  private final String contents;

  public CaseInsensitiveString( String contents){ this.contents = contents; }

  public boolean equals( Object o ){
    return o != null && o.getClass() == getClass() && o.contents.equalsIgnoreCase( contents);
  }

  public int hashCode(){
    return o.toUpperCase().hashCode();
  }
}


ArrayList의는 () 메서드는 제공하는 객체를 포함합니다 (배열의 객체가 아님)에서 같음 () 메서드를 호출하여 동등성을 확인합니다. 약간의 약간의 해킹 방법에 래퍼를 만드는 것입니다.

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();
    }
}

그런 다음이를 사용하여 테스트를 수행 할 수 있습니다. "수동"테스트 케이스의 예 :

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")));
    }
}

또 다른 해결책 :

public class IgnorecaseList extends ArrayList<String>{

    @Override
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    } 

    @Override
    public int indexOf(Object o) {
        if(o instanceof String){
            for (int i = 0; i < this.size(); i++) {
                if(((String)o).equalsIgnoreCase(get(i))){
                    return i;
                }
            }
        }
        return -1;
    }
}

contains()방법은 indexOf ...이 솔루션에서 위치가 인 위치도 알 수 있습니다. list.add("a")-> list.indexOf("A") == 0또는 list.indexOf("a") == 0..

목록 대신 집합을 사용하는 것도 좋습니다.


java8의 경우

list.stream (). anyMatch (s-> s.equalsIgnoreCase (yourString))

<java8 용

  • 위의 Aaron J Lang이 제안한 대로
  • 또는 목록의 대소 문자를 알고 있으면 (모두 대문자 / 모두 소문자) 비교하기 전에 검색하기 전에 대소 문자로 변환하십시오.

제 경우에는 ArrayList의 모든 문자열이 다운 케이스에 있으므로 String을 실행합니다. contains () 매개 변수에 대한 toLowerCase () 메서드. 이렇게 :

If (yourArrayList.contains (parameterInput.toLowerCase()) {
    // your code here
}

보시다시피 arrayList에 upperCase 문자열이 있으면 반대를 할 수 있습니다.

If (yourArrayList.contains (parameterInput.toUpperCase ()) {
    // your code here
}

이 접근 방식을 사용하면 아무것도 재정의 할 필요가 없습니다. 예외는 arrayList에 대문자와 소문자가 혼합 된 경우입니다.


나는 그렇게 만들 것입니다.

public boolean isStringInList(final List<String> myList, final String stringToFind) {
    return myList.stream().anyMatch(s -> s.equalsIgnoreCase(stringToFind));
}  

추가 기능이 필요하지 않으며 비교 된 문자열을 대문자 또는 소문자로 변환하여 원하는 결과를 얻을 수 있습니다.

(나는 이것이 의견에 제안되었지만 답변으로 철저히 제공되지는 않았습니다)

예 : JTextField에서 제공된 입력을 기반으로 JList의 내용을 필터링하는 동안 대소 문자를 무시합니다.

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.
     */
}

바퀴를 재발 명하지 마십시오. 잘 테스트 된 API를 사용하십시오. 귀하의 목적을 위해 Apache Commons StringUtils를 사용하십시오 .

Javadoc에서 : 주어진 문자열을 searchStrings의 CharSequences vararg와 비교하여 문자열이 대소 문자를 무시하고 searchStrings 중 하나와 같으면 true를 반환합니다.

import org.apache.commons.lang3.StringUtils;
...
StringUtils.equalsAnyIgnoreCase(null, (CharSequence[]) null) = false
StringUtils.equalsAnyIgnoreCase(null, null, null)    = true
StringUtils.equalsAnyIgnoreCase(null, "abc", "def")  = false
StringUtils.equalsAnyIgnoreCase("abc", null, "def")  = false
StringUtils.equalsAnyIgnoreCase("abc", "abc", "def") = true
StringUtils.equalsAnyIgnoreCase("abc", "ABC", "DEF") = true

목록 항목을 소문자로 변환하는 가장 좋은 방법입니다. 변환 후 contain 메서드를 사용합니다. 처럼

List<String> name_list = new ArrayList<>();
name_list.add("A");
name_list.add("B");

위에서 만든 것을 사용하여 소문자 목록 만들기 name_list

List<String> name_lowercase_list = new ArrayList<>();
for(int i =0 ; i<name_list.size(); i++){
 name_lowercase_list.add(name_list.get(i).toLowerCase().toString()); 
}

for(int i =0 ; i<name_list.size(); i++){
  String lower_case_name =  name_list.get(i).toLowerCase().toString();
  if(name_list.get(i).contains(your compare item) ||
   name_lowercase_list.get(i).contains(your compare item) ){
     //this will return true
   }
}

새 함수를 생성하지 않으려면 다음 방법을 시도해 볼 수 있습니다.

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
   }
}

compareToIgnoreCase, http://docs.oracle.com/javase/1.3/docs/api/java/lang/String.html#compareToIgnoreCase%28java.lang.String%29사용 하면 원하는 작업을 수행 할 수 있습니다!

참고 URL : https://stackoverflow.com/questions/8751455/arraylist-contains-case-sensitivity

반응형