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[]
?
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);
}