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', '', '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[]? Thanks for your answers

Answer

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(".*[/nrtf`?*\\<>|":].*");

public static boolean fineNameIsValidRegex(String fileName) {
    return !ILLEGAL_CHARACTERS_REGEX.matcher(fileName).matches();
}

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', '', 'f', '`', '?', '*', '\', '<', '>', '|', '"', ':'}) {
        ILLEGAL_CHARACTERS.set(c);
    }
}

public static boolean fileNameIsValid(String fileName) {
    return fileName.chars().noneMatch(ILLEGAL_CHARACTERS::get);
}

Leave a Reply

Your email address will not be published. Required fields are marked *