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

时间:2021-03-12 09:15:18

标签: java string java-stream character contains

我想检查作为文件名的字符串是否包含来自 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);
    }
}

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

4 个答案:

答案 0 :(得分:5)

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

<!DOCTYPE html>
<html>
<body>
  <gcse:search enablehistory="false"></gcse:search>
  <gcse:test enablehistory="false"></gcse:test>
  <mynamespace:testing enablehistory="false">test</mynamespace:testing>
</body>
</html>

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

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

答案 1 :(得分:3)

您可以尝试使用indexOf

return Arrays.stream(ILLEGAL_CHARACTERS)
             .map(fileName::indexOf)
             .anyMatch(i -> i >= 0);

答案 2 :(得分:2)

首先,我建议你使用 Set 而不是数组,因为你不需要索引你的东西,然后流过给定字符串中的字符,并检查是否有与您的组合的任何匹配。

从字符串的 chars() 方法中获取字符,这将为您提供一个整数数组,然后您可以将其转换为字符“数组”

这里有你需要的一切:

private static final Set<Character> ILLEGAL_CHARACTERS = Set.of(
        '/','\n','\r','\t','\0','\f','`','?','*','\\','<','>','|','\"',':');

public static boolean fileNameIsValid(String fileName) {
    return fileName.chars()
            .mapToObj(c -> (char) c)
            .noneMatch(ILLEGAL_CHARACTERS::contains);
}

答案 3 :(得分:0)

如果 contains 方法需要一个 CharSequence 而不是 char,那么您可以给它

Arrays.stream(ILLEGAL_CHARACTERS)
        .map(String::valueOf)
        .anyMatch(fileName::contains);

但是在 String 类中,这个方法使用了 indexOf(String str) 方法:

public boolean contains(CharSequence s) {
    return indexOf(s.toString()) > -1;
}

所以,为了避免多余的类型转换,你可以使用另一个indexOf(int ch)方法:

Arrays.stream(ILLEGAL_CHARACTERS).anyMatch(ch -> fileName.indexOf(ch) > -1);

另见:How to “subtract” 2 given strings In Java?