即时创建谓词

Creating Predicates on the fly

我有一个用户输入的 String[],我想根据设备的主机名是否包含任何用户输入来过滤设备集合。

我正在尝试按照课程 https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html 来执行此操作。

interface PredicateOperation{
    Predicate operation(String[] input);
}

public Predicate getPredicate(String[] input, PredicateOperation op){
    return op.operation(input);
}

private TufinDeviceCollection<TufinDevice> filter(TufinDeviceCollection<TufinDevice> devices) {        

       //Check if any HostNames of the devices contain any of the items in String[] modelContains

            devices = devices.stream()
                    .sequential()
                    .filter(//How do i create this predicate?)//we need to create the lamda expression to evaulate if the hostName of device d contains any of the items String[] userInput
                    .collect(Collectors.toCollection(TufinDeviceCollection<TufinDevice>::new));

    }

我不清楚如何定义 .filter(..) 中的 PredicateOperation

device -> Stream.of(inputs).anyMatch(input -> device.hostName.contains(input))
.filter(device -> Arrays.stream(userInput)
                        .anyMatch(input -> device.getHostName().contains(input)))

但是您需要 String[] userInput 才能通过 filter 方法访问。

我猜这是尝试编写自己的 @FunctionalInterface 来替换标准 Predicate<T>

interface PredicateOperation {
    Predicate operation(String[] input);
}

虽然不是很实用。

PredicateOperation operation = (String[] input) -> ((Object o) -> true);

如果我可以 return 结果,为什么我需要 return Predicate?稍微增强的版本是

interface PredicateOperation {
    boolean operation(String[] input);
}

PredicateOperation operation = (String[] input) -> true;

这对于 Stream API 仍然不是特别有用,因为 Stream#filter 需要 java.util.function.Predicate<T>,而不是您的类型。

并且,是的,停止使用原始 Predicates。

出于可读性和可重用性的目的,我更喜欢在单独的行中分隔谓词并稍后在 filter() 上应用它。所以代码有点像:

private TufinDeviceCollection<TufinDevice> filter(TufinDeviceCollection<TufinDevice> devices) {        

   Predicate< ? super TufinDevice> deviceFilter = device -> Arrays.stream(userInput)
                                                 .anyMatch(input -> device.getHostName().contains(input));

   devices = devices.stream()
                .sequential()
                .filter(deviceFilter)
                .collect(Collectors.toCollection(TufinDeviceCollection<TufinDevice>::new));

}