I need some help. I created a functional interface that has one abstract method called filter:
@FunctionalInterface
interface FileFilter {
/**
* This method gets a file path and filters it in some method.
* @return a list of the remaining files after this filter.
* @throws IOException
*/
abstract boolean filter(Path path) throws IOException;
}
I need to create a few different implementations of this method devided into two groups:
1. A few that filter by different file sizes (the difference between them is the criterion).
2. A few that filter by different file name. (the only difference between them is a single choice of String method - contains
/ startsWith
etc.
It seems stupid to me to create a different function that implements my filter
method for each of these when they are so similar, but I can't think of a way to overcome this.
I would like to write one function (the returns a correct lambda) for each group.
For example, right now the methods that create filters from the second group look like this:
static FileFilter prefixFilter(String[] parameters, int expectedLength) throws
BadParameterFilterException{
String value = parameters[0];
if(doesContainNOTSuffix(parameters.length, expectedLength, parameters[parameters.length-1])){
return path -> !(path.getFileName().toString().startsWith(value);
}
return path -> (path.getFileName().toString().startsWith(value);
}
/**
* This class implements the suffix filter.
* @param parameters given command paramaters.
* @param expectedLength the expected length of the command with a NOT suffix.
* @return lambda function of the greater_than filter.
* @throws BadParameterFilterException
*/
static FileFilter suffixFilter(String[] parameters, int expectedLength) throws
BadParameterFilterException{
String value = parameters[0];
if(doesContainNOTSuffix(parameters.length, expectedLength, parameters[parameters.length-1])){
return path -> !(path.getFileName().toString().endsWith(value);
}
return path -> (path.getFileName().toString().endsWith(value);
}
They differ only in the String method used in the lambda. I would like to combine them into one, but you can't pass a method as a varible.
Thank you!
Just to combine the two methods shown into one, you can add another BiPredicate<String, String>
parameter.
static FileFilter stringFilter(String[] parameters, int expectedLength, BiPredicate<String, String> stringPredicate) throws
BadParameterFilterException{
String value = parameters[0];
if(doesContainNOTSuffix(parameters.length, expectedLength, parameters[parameters.length-1])){
return path -> !stringPredicate.test(path.getFileName().toString(), value);
}
return path -> stringPredicate.test(path.getFileName().toString(), value);
}
And pass (x, y) -> x.endsWith(y)
and (x, y) -> x.startsWith(y)
to it in the two cases respectively.
As with the file size predicates, you can probably do it with the same approach.