【问题标题】:Creating Predicates on the fly动态创建谓词
【发布时间】:2019-07-30 21:07:12
【问题描述】:

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

我正在尝试遵循 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

【问题讨论】:

  • 我不清楚你到底想做什么,但作为澄清的第一步——包括你自己——停止使用原始Predicates。适当地参数化该类型的所有用途。

标签: java lambda predicate


【解决方案1】:
.filter(device -> Arrays.stream(userInput)
                        .anyMatch(input -> device.getHostName().contains(input)))

但您需要通过filter 方法访问String[] userInput

我猜这是尝试编写自己的@FunctionalInterface 来替换标准的Predicate&lt;T&gt;

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

不过,这不是很实用。

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

如果我可以返回结果,为什么我需要返回 Predicate?一点增强版本将是

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

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

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

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

【讨论】:

  • 我的想法是我将重用该接口,以便在 device.ip、.hostname 等上即时执行其他过滤器
  • @JamieSnipes 你为什么不喜欢Predicate&lt;String[]&gt;
  • 我真的不知道我更喜欢什么。这是我的第一次尝试。
【解决方案2】:
device -> Stream.of(inputs).anyMatch(input -> device.hostName.contains(input))

【讨论】:

  • 我觉得你应该加个解释
【解决方案3】:

出于可读性和可重用性的目的,我更喜欢将谓词分隔在单独的行上,然后在 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));

}

【讨论】:

    猜你喜欢
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    相关资源
    最近更新 更多