¿Cómo lo hago de una mejor manera? Prefiero la sintaxis java8.

Estas condiciones booleanas podrían crecer.

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         
}
-1
Ilakk. Manoharan 8 sep. 2018 a las 00:09

3 respuestas

La mejor respuesta

Aquí hay un par de maneras de hacer esto más "escalable".

  1. Use una expresión regular:

    Pattern p = Pattern.compile("^video|^audio|^image|zip|rar|java-archive|x-tar");
    if (!p.matcher(filetype).find()) {
        // do stuff
    }
    
  2. Use matrices o listas. Por ejemplo:

    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
    }
    

Claramente, el enfoque de expresiones regulares es más conciso, pero el enfoque de matriz es probablemente más eficiente (¡si eso importa!). Depende de cómo el motor regex hace frente a una expresión regular con muchas alternativas.

Ambos enfoques se escalarán; por ejemplo, actualizando la expresión regular o agregando cadenas a las matrices.

En ambos casos, puede cargar fácilmente los criterios relevantes de un archivo de propiedades o similar ... y evitar hacer cambios en el código.

No estoy convencido de que las lambdas y las transmisiones de Java 8 sean adecuadas para este problema.

0
Stephen C 12 sep. 2018 a las 00:59

También podría usarse un enfoque más orientado a objetos para brindarle un poco más de información sobre el tipo de archivo. Me imagino que será útil más adelante en su programa.

Podría hacer algo como declarar todos sus tipos de archivo en un 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;
    }
}

Luego, en su función, puede reemplazar todos sus Booleans con una verificación para ver si su entrada String1 es un tipo de archivo incluido:

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

Como tiene 7 cadenas diferentes para verificar, puede agregar una simple verificación para ver si todas las variables String1 coinciden:

boolean isNotFileType = Stream
    .of(String1, String2, String3, String4, String5, String6, String7)
    .map(FileType::getFileTypeForStr)
    .anyMatch(Objects::isNull);
1
nbokmans 7 sep. 2018 a las 21:36

1) Reagrupa tus condiciones en Predicate s. Tome el caso de una enumeración:

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) Use Stream # reduce y Predicate # o para crear un solo Predicate que sea el resultado de todos sus predicados conectados por operadores lógicos 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) Utilice el resultado de Predicate # test en tu declaración if. Por ejemplo, el código anterior imprime:

image.png: true
my-archive.txt: true
foo : false
0
Gustavo Passini 8 sep. 2018 a las 03:24