【问题标题】:What is the better way for if condition with multiple OR in java? Java8 is preferable在java中具有多个OR的if条件的更好方法是什么? Java8 更可取
【发布时间】:2019-02-13 05:27:23
【问题描述】:

如何以更好的方式做到这一点?我更喜欢 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 件事,没有办法避免运行这些检查。特别是因为您正在检查不同的字符串。
  • 您是否在 if 语句之外使用这些布尔值?如果没有,您可以将它们合并为 1 个布尔值。
  • 这看起来有点像 X-Y 问题。坦率地说,带有String1...StringN(和String6 出现两次)的原始代码本身并没有多大意义。您要解决的实际问题是什么?

标签: java conditional


【解决方案1】:

也可以使用更面向对象的方法为您提供有关文件类型的更多信息。我可以想象它稍后在您的程序中很有用。

您可以在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);

【讨论】:

    【解决方案2】:

    这里有几个方法可以让这个更“可扩展”。

    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 lambda 和流非常适合这个问题。

    【讨论】:

      【解决方案3】:

      1) 重新组合Predicates 中的条件。以枚举为例:

      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) 使用 Stream#reducePredicate#or 创建一个 Predicate,它是由逻辑 OR 运算符连接的所有谓词的结果:

      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 语句中使用Predicate#test 的结果。比如上面的代码打印出来:

      image.png: true
      my-archive.txt: true
      foo : false
      

      【讨论】:

        猜你喜欢
        • 2015-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 2015-03-25
        • 1970-01-01
        相关资源
        最近更新 更多