IT박스

하나의 표현식에서 하나의 문자열을 여러 값과 비교

itboxs 2020. 12. 10. 19:43
반응형

하나의 표현식에서 하나의 문자열을 여러 값과 비교


나는 하나 개의 문자열 변수가 str사용할 수있는 값과를 val1, val2하고 val3.

str예를 들어 if 문을 사용하여 이러한 모든 값 을 비교하고 싶습니다 (동일한 경우) .

if("val1".equalsIgnoreCase(str)||"val2".equalsIgnoreCase(str)||"val3.equalsIgnoreCase(str))
{
      //remaining code
}

여러 OR (||) 연산자를 사용하지 않고 하나의 표현식에서 값을 비교하는 방법이 있습니까? 예를 들면 다음과 같습니다.

 if(("val1" OR "val2" OR "val3").equalsIgnoreCase(str)   //this is only an idea.

더 나은 해결책을 찾았습니다. 이것은 RegEx를 통해 달성 할 수 있습니다.

if (str.matches("val1|val2|val3")) {
     // remaining code
}

대소 문자를 구분하지 않는 일치 :

if (str.matches("(?i)val1|val2|val3")) {
     // remaining code
}

Java 8 이상에서는 Stream<T>anyMatch(Predicate<? super T>)다음과 같이 사용할 수 있습니다.

if (Stream.of("val1", "val2", "val3").anyMatch(str::equalsIgnoreCase)) {
    // ...
}

비교할 모든 문자열을 str컬렉션에 저장하고 컬렉션에 str. 컬렉션의 모든 문자열을 소문자로 저장하고 컬렉션을 str쿼리하기 전에 소문자 로 변환 합니다. 예를 들면 :

Set<String> strings = new HashSet<String>();
strings.add("val1");
strings.add("val2");

String str = "Val1";

if (strings.contains(str.toLowerCase()))
{
}

ArrayUtils 도움이 될 수 있습니다.

ArrayUtils.contains(new String[]{"1", "2"}, "1")

완벽하게 유효한 @hmjd의 대답에 대한 작은 향상 : 다음 구문을 사용할 수 있습니다.

class A {

  final Set<String> strings = new HashSet<>() {{
    add("val1");
    add("val2");
  }};

  // ...

  if (strings.contains(str.toLowerCase())) {
  }

  // ...
}

Set제자리에서 초기화 할 수 있습니다 .


var-args를 사용하고 고유 한 정적 메서드를 작성하십시오.

public static boolean compareWithMany(String first, String next, String ... rest)
{
    if(first.equalsIgnoreCase(next))
        return true;
    for(int i = 0; i < rest.length; i++)
    {
        if(first.equalsIgnoreCase(rest[i]))
            return true;
    }
    return false;
}

public static void main(String[] args)
{
    final String str = "val1";
    System.out.println(compareWithMany(str, "val1", "val2", "val3"));
}

아파치 공용 라이브러리에서 StringUtils를 사용 하는 또 다른 대안 ( 위의 https://stackoverflow.com/a/32241628/6095216 과 유사 ) : https://commons.apache.org/proper/commons-lang/apidocs/org/ apache / commons / lang3 / StringUtils.html # equalsAnyIgnoreCase-java.lang.CharSequence-java.lang.CharSequence ...-

if (StringUtils.equalsAnyIgnoreCase(str, "val1", "val2", "val3")) {
  // remaining code
}

다음은 여러 대안을 사용한 성능 테스트입니다 (일부는 대소 문자를 구분하고 다른 일부는 대소 문자를 구분하지 않음).

public static void main(String[] args) {
    // Why 4 * 4:
    // The test contains 3 values (val1, val2 and val3). Checking 4 combinations will check the match on all values, and the non match;
    // Try 4 times: lowercase, UPPERCASE, prefix + lowercase, prefix + UPPERCASE;
    final int NUMBER_OF_TESTS = 4 * 4;
    final int EXCUTIONS_BY_TEST = 1_000_000;
    int numberOfMatches;
    int numberOfExpectedCaseSensitiveMatches;
    int numberOfExpectedCaseInsensitiveMatches;
    // Start at -1, because the first execution is always slower, and should be ignored!
    for (int i = -1; i < NUMBER_OF_TESTS; i++) {
        int iInsensitive = i % 4;
        List<String> testType = new ArrayList<>();
        List<Long> timeSteps = new ArrayList<>();
        String name = (i / 4 > 1 ? "dummyPrefix" : "") + ((i / 4) % 2 == 0 ? "val" : "VAL" )+iInsensitive ;
        numberOfExpectedCaseSensitiveMatches = 1 <= i && i <= 3 ? EXCUTIONS_BY_TEST : 0;
        numberOfExpectedCaseInsensitiveMatches = 1 <= iInsensitive && iInsensitive <= 3 && i / 4 <= 1 ? EXCUTIONS_BY_TEST : 0;
        timeSteps.add(System.currentTimeMillis());
        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("List (Case sensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (Arrays.asList("val1", "val2", "val3").contains(name)) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("Set (Case sensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (new HashSet<>(Arrays.asList(new String[] {"val1", "val2", "val3"})).contains(name)) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("OR (Case sensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if ("val1".equals(name) || "val2".equals(name) || "val3".equals(name)) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("OR (Case insensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if ("val1".equalsIgnoreCase(name) || "val2".equalsIgnoreCase(name) || "val3".equalsIgnoreCase(name)) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseInsensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("ArraysBinarySearch(Case sensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (Arrays.binarySearch(new String[]{"val1", "val2", "val3"}, name) >= 0) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("Java8 Stream (Case sensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (Stream.of("val1", "val2", "val3").anyMatch(name::equals)) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("Java8 Stream (Case insensitive)");
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (Stream.of("val1", "val2", "val3").anyMatch(name::equalsIgnoreCase)) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseInsensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("RegEx (Case sensitive)");
        // WARNING: if values contains special characters, that should be escaped by Pattern.quote(String)
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (name.matches("val1|val2|val3")) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("RegEx (Case insensitive)");
        // WARNING: if values contains special characters, that should be escaped by Pattern.quote(String)
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            if (name.matches("(?i)val1|val2|val3")) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseInsensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        numberOfMatches = 0;
        testType.add("StringIndexOf (Case sensitive)");
        // WARNING: the string to be matched should not contains the SEPARATOR!
        final String SEPARATOR = ",";
        for (int j = 0; j < EXCUTIONS_BY_TEST; j++) {
            // Don't forget the SEPARATOR at the begin and at the end!
            if ((SEPARATOR+"val1"+SEPARATOR+"val2"+SEPARATOR+"val3"+SEPARATOR).indexOf(SEPARATOR + name + SEPARATOR)>=0) {
                numberOfMatches++;
            }
        }
        if (numberOfMatches != numberOfExpectedCaseSensitiveMatches) {
            throw new RuntimeException();
        }
        timeSteps.add(System.currentTimeMillis());

        //-----------------------------------------
        StringBuffer sb = new StringBuffer("Test ").append(i)
                .append("{ name : ").append(name)
                .append(", numberOfExpectedCaseSensitiveMatches : ").append(numberOfExpectedCaseSensitiveMatches)
                .append(", numberOfExpectedCaseInsensitiveMatches : ").append(numberOfExpectedCaseInsensitiveMatches)
                .append(" }:\n");
        for (int j = 0; j < testType.size(); j++) {
            sb.append(String.format("    %4d ms with %s\n", timeSteps.get(j + 1)-timeSteps.get(j), testType.get(j)));
        }
        System.out.println(sb.toString());
    }
}

출력 (더 나쁜 경우에만 일치하지 않는 모든 요소를 ​​확인해야하는 경우) :

Test 4{ name : VAL0, numberOfExpectedCaseSensitiveMatches : 0, numberOfExpectedCaseInsensitiveMatches : 0 }:
  43 ms with List (Case sensitive)
 378 ms with Set (Case sensitive)
  22 ms with OR (Case sensitive)
 254 ms with OR (Case insensitive)
  35 ms with ArraysBinarySearch(Case sensitive)
 266 ms with Java8 Stream (Case sensitive)
 531 ms with Java8 Stream (Case insensitive)
1009 ms with RegEx (Case sensitive)
1201 ms with RegEx (Case insensitive)
 107 ms with StringIndexOf (Case sensitive)

Collections 프레임 워크로이를 달성 할 수 있습니다. 컬렉션에 모든 옵션을 넣으십시오 Collection<String> options.

그런 다음 이것을 반복하여 문자열을 목록 요소와 비교하고 부울 값 true를 반환하고 그렇지 않으면 false를 반환 할 수 있습니다.


Remember in Java a quoted String is still a String object. Therefore you can use the String function contains() to test for a range of Strings or integers using this method:

if ("A C Viking G M Ocelot".contains(mAnswer)) {...}

for numbers it's a tad more involved but still works:

if ("1 4 5 9 10 17 23 96457".contains(String.valueOf(mNumAnswer))) {...} 

Apache Commons Collection class.

StringUtils.equalsAny(CharSequence string, CharSequence... searchStrings)

So in your case, it would be

StringUtils.equalsAny(str, "val1", "val2", "val3");


No, there is no such possibility. Allthough, one could imagine:

public static boolean contains(String s, Collection<String>c) {
    for (String ss : c) {
       if (s.equalsIgnoreCase(ss)) return true;
    }
    return false;
}

!string.matches("a|b|c|d") 

works fine for me.

참고URL : https://stackoverflow.com/questions/10205437/compare-one-string-with-multiple-values-in-one-expression

반응형