簡體   English   中英

檢查字符串是否包含數組中的字符

[英]Check that string contains a character from array

我想檢查作為文件名的字符串是否包含來自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 stream 有什么方法可以做到這一點,而無需將Character[]類型更改為String[]

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

或者,如果您的非法字符集僅限於 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);
}

您可以嘗試使用indexOf

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

首先,我建議您使用Set而不是數組,因為您不需要索引您的東西,然后 Stream 覆蓋給定字符串中的字符,並檢查是否與您的集合匹配。

從字符串上的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);
}

如果contains方法需要一個CharSequence而不是char ,那么你可以給它

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

但在String class 的內部,此方法使用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);

另請參閱:如何在 Java 中“減去”2 個給定的字符串?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM