Search code examples
javastringjava-streamcharactercontains

Check that string contains a character from array


I would like to check that string that is a filename contains a illegal argument from the ILLEGAL_CHARACTERS. Simply I could use for loop, but I want to do this by Streams.

My code:

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

Problem is in contains method cuz It needs a CharSequence instead of char. Is there any way to do this by stream without changing Character[] type to String[]?


Solution

  • Streams might not the best fit here. Also, now your solution has quadratic complexity (N*M, where N is the file name length, and M is the size of your illegal character array), which is not very performant. As proposed in the comments, you could use a regular expression:

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

    Or, if your illegal character set is limited to ASCII, you could play around with a bitset to squeeze some performance:

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