【问题标题】:Filtering collection with collection of predicates and conforming to threshold使用谓词集合过滤集合并符合阈值
【发布时间】:2019-03-17 20:50:41
【问题描述】:

我被困在我正在做的一个练习中,以进入函数式编程,所以我的主要问题是如何计算集合元素上传递的谓词以及它是否符合给定阈值而不是收集它最后的集合。

我知道如何做到没有门槛,这是我的解决方案:

List<String> filter(List<Predicate<String>> predicateList, List<String> stringList) {
    return stringList.stream()
                     .filter(predicateList.stream()
                                          .reduce(x -> !(x.isEmpty()), Predicate::and))
                     .collect(Collectors.toList());
}

但是当有一个参数决定需要传递多少百分比的谓词来收集字符串时,我该怎么办,假设方法的主体可能如下所示:

List<String> filtrr(List<Predicate<String>> predicateList, List<String> stringList, Double threshold) {}

编辑: 例如方法应该像这样通过单元测试:

@Test
void filtrrTest() {
    Double threshold = 0.65;

    Predicate<String> predicate = p -> p.contains("lorem");
    Predicate<String> predicate1 = p -> p.length() > 10;
    Predicate<String> predicate2 = p -> p.contains("sed");

    List<Predicate<String>> predicateList = Arrays.asList(predicate, predicate1, predicate2);

    String string = "lorem ipsum dolor sit amet sed";
    String string1 = "consectetur adipiscing elit, sed do eiusmod";
    String string2 = "ipsum";
    String string3 = "adipiscing elit";
    String string4 = "sed do eiusmod";

    List<String> stringList = Arrays.asList(string, string1, string2, string3, string4);
    List<String> expectedList = Arrays.asList(string, string1, string4);

    assertEquals(expectedList, ClassName.filtrr(predicateList, stringList, threshold));
}

【问题讨论】:

  • 你能举个例子说明你在这里想说什么吗?
  • 如果你在网上做这个“练习”。那么请发布它的描述:)。
  • @Aomine 不幸的是它不在线,这是我的朋友让我的生活变得糟糕的方式。一步一步:使用谓词列表过滤字符串列表 -> 检查有多少谓词从 test() 返回“真” -> 如果通过/predicatesList.size() > 阈值 -> 收集
  • @saturator22 好的,现在为了让您的帖子更清晰,请提供predicateListstringListthreshold 的一些示例数据,说明您希望返回的数据。
  • @FedericoPeraltaSchaffner 我知道,没有难过的感觉,每个反馈都是好的 :)

标签: java java-8 functional-programming java-stream predicate


【解决方案1】:

我将首先创建一个通用实用程序方法来检查给定元素是否与谓词的threshold % 匹配:

public static <T> boolean matchingSome(
        T elem, 
        List<Predicate<T>> predicates, 
        double threshold) {

    long predsToMatch = (long) ((double) predicates.size() * threshold);

    long predsMatched = predicates.stream()
        .filter(p -> p.test(elem))
        .limit(predsToMatch) // this limit is to short-circuit as soon as
        .count();            // predsToMatch predicates evaluate to true

    return predsMatched == predsToMatch;
}

请注意,一旦predsToMatch 谓词评估为true,我就会使流短路。这是为了避免继续评估进一步的谓词。

现在只需收集上述方法返回true的所有字符串:

List<String> result = stringList.stream()
    .filter(s -> matchingSome(s, predicateList, threshold))
    .collect(Collectors.toList());

【讨论】:

  • IIUC 如果单个谓词的threshold 评估为真,则他需要组合谓词为真。
  • @daniu 没错,但感谢您对 Federico 的支持
  • 非常感谢!现在我正在以不同的方式考虑 fp !已保存一天!
猜你喜欢
  • 2020-05-20
  • 1970-01-01
  • 2014-10-26
  • 2010-09-12
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
相关资源
最近更新 更多