检查字符串是否包含数组中的字符

Osk*_*kar 2 java string contains character java-stream

我想检查作为文件名的字符串包含来自ILLEGAL_CHARACTERS. 只是我可以使用 for 循环,但我想通过Streams来做到这一点。

我的代码:

package shared;

import java.util.Arrays;

public class Validator {
    private static final Character[] ILLEGAL_CHARACTERS =
            {'/','\n','\r','\t','\0','\f','`','?','*','\\','<','>','|','\"',':'};

    public static boolean fileNameIsValid(String fileName) {
        return Arrays.stream(ILLEGAL_CHARACTERS).anyMatch(fileName::contains);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题在于 contains 方法因为它需要一个CharSequence而不是char. 有没有办法通过流来做到这一点而不将Character[]类型更改为String[]

Ser*_*nin 5

Streams 可能不是这里的最佳选择。此外,现在您的解决方案具有二次复杂度(N*M,其中 N 是文件名长度,M 是非法字符数组的大小),性能不是很好。正如评论中所建议的,您可以使用正则表达式:

private static final Pattern ILLEGAL_CHARACTERS_REGEX =
        Pattern.compile("[/\n\r\t\0\f`?*\\\\<>|\":]");

public static boolean fileNameIsValidRegex(String fileName) {
    return !ILLEGAL_CHARACTERS_REGEX.matcher(fileName).find();
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您的非法字符集仅限于 ASCII,您可以使用 bitset 来提高性能:

private static final BitSet ILLEGAL_CHARACTERS = new BitSet();

static {
    for (char c : new char[]{
            '/','\n','\r','\t','\0','\f','`','?','*','\\','<','>','|','\"',':'}) {
        ILLEGAL_CHARACTERS.set(c);
    }
}

public static boolean fileNameIsValid(String fileName) {
    return fileName.chars().noneMatch(ILLEGAL_CHARACTERS::get);
}
Run Code Online (Sandbox Code Playgroud)