目前还不是很清楚你到底想达到什么目标。我假设您想创建一些通用解决方案来以相同的方式验证所有数组元素,然后将其专门用于各种元素类型。
为了解决这个问题,我推荐以下方法。使ArrayPredicate<T> 不是类,而是另一个扩展Predicate<T[]> 并提供验证数组元素的抽象方法的接口。整个界面可能是这样的:
import java.util.Arrays;
import java.util.function.Predicate;
@FunctionalInterface
public interface ArrayPredicate<T> extends Predicate<T[]> {
public boolean testElement(T t);
default public boolean test(T[] a) {
if (a == null || a.length == 0)
return false;
return Arrays.stream(a).allMatch(this::testElement);
}
}
之后你可以像这样定义特定的谓词:
public class NonNullArrayPredicate implements ArrayPredicate<Object> {
@Override
public boolean testElement(Object obj) {
return obj != null;
}
}
public class NonEmptyStringArrayPredicate implements ArrayPredicate<String> {
@Override
public boolean testElement(String str) {
return str != null && !str.isEmpty();
}
}
等等。尽管 Java-8 的方式可能是完全删除这些类并使用 lambda:
ArrayPredicate<Object> nonNullObjectArrayPredicate = Objects::nonNull;
ArrayPredicate<String> nonEmptyStringArrayPredicate = str -> str != null && str.isEmpty();
另一种更实用的解决方案是完全摆脱 ArrayPredicate 并创建单个高阶函数,而不是将元素谓词转换为数组谓词:
// In any suitable class
public static <T> Predicate<T[]> forArray(Predicate<T> elementPredicate) {
return a -> a != null && a.length != 0 &&
Arrays.stream(a).allMatch(elementPredicate);
};
}
这样你可以像这样创建特定的谓词:
Predicate<Object[]> nonNullObjectArrayPredicate = forArray(Objects::nonNull);
Predicate<String[]> nonEmptyStringArrayPredicate = forArray(
str -> str != null && str.isEmpty());
因此您不需要声明任何新类,只需声明函数即可。