Какой лучший способ для условия if с несколькими OR в java? Java8 предпочтительнее

Как мне сделать это лучше? Я предпочитаю синтаксис java8.

Эти логические условия могут увеличиваться.

boolean imageType = filetype.startsWith("image");

boolean videoType = filetype.startsWith("video");

boolean archiveType = filetype.contains("archive");

boolean jarType = filetype.contains("java-archive");

boolean audioType = filetype.startsWith("audio");

boolean zipType = filetype.contains("zip");

boolean xTarType = filetype.contains("x-tar");

boolean rarType = filetype.contains("rar");

if (!(imageType || videoType || archiveType || jarType || audioType || zipType || xTarType)) {
         //doSomething         
}

Если вы хотите проверить 7 вещей, не избежать выполнения этих проверок. Тем более, что вы проверяете разные строки.

Nir Alfasi 07.09.2018 23:12

Вы используете эти логические значения вне этого оператора if? В противном случае вы можете объединить их в одно логическое значение.

Matthew 07.09.2018 23:13

Это немного похоже на вопрос XY. Исходный код сам по себе с String1 ... StringNString6, появляющийся дважды), откровенно говоря, не имеет большого смысла. Какую проблему вы пытаетесь решить?

Mick Mnemonic 07.09.2018 23:30
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
269
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Можно также использовать более объектно-ориентированный подход, чтобы дать вам немного больше информации о типе файла. Я могу представить, что это пригодится позже в вашей программе.

Вы можете сделать что-то вроде объявления всех типов файлов в Enum:

public enum FileType {
    IMAGE("a"),
    VIDEO("b"),
    ARCHIVE("c"),
    JAR("d"),
    AUDIO("e"),
    ZIP("f"),
    XTAR("g");

    private String str;

    FileType(String str) {
        this.str = str;
    }

    public String getStr() {
        return str;
    }

    public static FileType getFileTypeForStr(String str) {
        for (FileType fileType : FileType.values()) {
            if (fileType.getStr().equalsIgnoreCase(str)) {
                return fileType;
            }
        }

        return null;
    }
}

Затем в своей функции вы можете заменить все свои Booleans проверкой, чтобы увидеть, является ли ваш входной String1 включенным типом файла:

FileType fileType = FileType.getFileTypeForStr(String1); //And String2, String3, String4...
if (fileType != null) {
    System.out.printf("File type found of type %s", fileType.name());
} else {
    System.out.printf("No file type found for input %s", String1);
}

Поскольку у вас есть 7 разных строк для проверки, вы можете добавить простую проверку, чтобы убедиться, что все переменные String1 совпадают:

boolean isNotFileType = Stream
    .of(String1, String2, String3, String4, String5, String6, String7)
    .map(FileType::getFileTypeForStr)
    .anyMatch(Objects::isNull);

1) Перегруппируйте свои условия в Предикат. Возьмем случай с Enum:

public enum PredicateEnum {

    IMAGE   (filetype -> filetype.startsWith("image")),
    VIDEO   (filetype -> filetype.startsWith("video")),
    ARCHIVE (filetype -> filetype.contains("archive")),
    JAR     (filetype -> filetype.contains("java-archive")),
    AUDIO   (filetype -> filetype.startsWith("audio")),
    ZIP     (filetype -> filetype.contains("zip")),
    X_TAR   (filetype -> filetype.contains("x-tar")),
    RAR     (filetype -> filetype.contains("rar"));

    private Predicate<String> predicate;

    PredicateEnum(Predicate<String> predicate) {
        this.predicate = predicate;
    }

    public Predicate<String> getPredicate() {
        return predicate;
    }
}

2) Используйте Поток # уменьшить и Предикат № или для создания единого предиката, который является результатом всех ваших предикатов, связанных логическими операторами ИЛИ:

Predicate<String> predicateOr = Stream.of(PredicateEnum.values())
        .map(PredicateEnum::getPredicate)
        .reduce(Predicate::or)
        .orElse(s -> false);

System.out.println("image.png: "      + predicateOr.test("image.png"));
System.out.println("my-archive.txt: " + predicateOr.test("my-archive.txt"));
System.out.println("foo : "           + predicateOr.test("foo"));

3) Используйте результат Предикат # тест в своем операторе if. Например, приведенный выше код распечатывает:

image.png: true
my-archive.txt: true
foo : false
Ответ принят как подходящий

Вот несколько способов сделать это более «масштабируемым».

  1. Используйте регулярное выражение:

    Pattern p = Pattern.compile("^video|^audio|^image|zip|rar|java-archive|x-tar");
    if (!p.matcher(filetype).find()) {
        // do stuff
    }
    
  2. Используйте массивы или списки. Например:

    String[] prefixes = new String[]{"video", "audio", "images"};
    String[] contains = new String[]{"zip", "rar", "x-tar", "jar-archive"};
    boolean match = false;
    for (String p : prefixes) {
        if (filetype.startsWith(p)) {
            match = true;
        }
    }
    ...
    if (!match) {
        // do stuff
    }
    

Очевидно, что подход с использованием регулярных выражений более краток, но подход с использованием массива, вероятно, более эффективен (если это имеет значение!). Это зависит от того, как движок регулярных выражений справляется с регулярным выражением с множеством альтернатив.

Оба подхода будут масштабироваться; например, обновив регулярное выражение или добавив строки в массивы.

В обоих случаях вы можете легко загрузить соответствующие критерии из файла свойств или аналогичного ... и избежать внесения изменений в код.

Я не уверен, что лямбды и потоки Java 8 подходят для этой проблемы.

Другие вопросы по теме