Подтвердить что ты не робот

Сравните одну строку с несколькими значениями в одном выражении

У меня есть одна переменная String, 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.
4b9b3361

Ответ 1

Я нашел лучшее решение. Это может быть достигнуто через RegEx:

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

Для сопоставления без учета регистра:

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

Ответ 2

В Java 8+ вы можете использовать Stream<T> и anyMatch(Predicate<? super T>) с чем-то вроде

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

Ответ 3

Вы можете сохранить все строки, которые вы хотите сравнить str с коллекцией, и проверить, содержит ли коллекция str. Сохраните все строки в коллекции как строчные буквы и преобразуйте str в нижний регистр перед запросом коллекции. Например:

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

String str = "Val1";

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

Ответ 4

ArrayUtils может быть полезно.

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

Ответ 5

Малое усиление до абсолютно достоверного @hmjd answer: вы можете использовать следующий синтаксис:

class A {

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

  // ...

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

  // ...
}

Он позволяет вам инициализировать вас Set на месте.

Ответ 6

Просто используйте 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"));
}

Ответ 8

Вы можете добиться этого с помощью структуры Collections. Поместите все свои варианты в коллекцию, скажем что-то вроде Collection<String> options;

Затем запустите цикл, чтобы сравнить вашу строку с элементами списка, и если это так, вы можете вернуть логическое значение true и в противном случае false.

Ответ 9

Помните, что в Java строка String по-прежнему является объектом String. Поэтому вы можете использовать функцию String contains() для проверки диапазона строк или целых чисел с помощью этого метода:

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

для чисел он еще более задействован, но все еще работает:

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

Ответ 10

Класс Apache Commons Collection.

StringUtils.equalsAny (строка CharSequence, последовательность CharSequence... searchStrings)

Так что в вашем случае это было бы

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

Ответ 11

Здесь тест производительности с несколькими альтернативами (некоторые чувствительны к регистру, а другие нечувствительны к регистру):

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)

Ответ 12

Нет, такой возможности нет. Во всяком случае, можно было представить:

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

Ответ 13

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

отлично работает для меня.