【问题标题】:Externally configurable filtering using Java lambdas使用 Java lambda 进行外部可配置过滤
【发布时间】:2017-10-14 08:13:28
【问题描述】:

假设我有一个外部 JSON:

[{
    "condition": "equals",
    "field": "name",
    "value": "jack"
  },
  {
    "condition": "greater",
    "field": "age",
    "value": 25
  }
]

这意味着我想在 Person 对象列表中检查名称为 "jack"age > 25 的人。使用 Java 8 过滤非常简单(显示的示例仅按名称过滤)。

但是,我想让这个过滤器可配置并应用多个过滤器。假设下面的 Person pojo(不言自明),需要姓名和年龄,我怎样才能使过滤器动态或可配置?

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // Accessors and Mutators
}
List<Person> persons = Arrays.asList(
    new Person("mkyong", 30),
    new Person("jack", 20),
    new Person("lawrence", 40)
);

Person result1 = persons.stream()            // Convert to steam
    .filter(x -> "jack".equals(x.getName())) // we want "jack" only
    .findAny()                               // If 'findAny' then return found
    .orElse(null);  

我期待一个满足标准的 Person 对象列表。

【问题讨论】:

    标签: java lambda filter java-8 java-stream


    【解决方案1】:

    据我所知,这与streams 本身没什么关系。该过滤器方法只是一个Predicate,可以作为实例提供,例如从您可以创建的工厂方法中提供。

    static Predicate<Person> fromName(String value){
        return p -> p.getName().equals(value);
    }
    

    假设你有另一种方法:

    static Predicate<Person> fromAge(int value) {
        return p -> p.getAge() == value;
    }
    

    因为Predicate.andPredicate.or 存在,你可以这样做:

     fromAge(12).and(fromName("jack"));
    

    因此链接你的谓词

    【讨论】:

      【解决方案2】:

      对此有两种方法。

      您可以直接内联调用所需的过滤器:

      Person result1 = persons.stream()
          .filter(x -> "jack".equals(x.getName()))
          .filter(x -> 25 > x.getAge()) // new filter
          .findAny()
          .orElse(null);
      

      或者,您有自己的类实现Predicate&lt;Person&gt;

      在这种情况下,您可以使用构建器模式逐步构建您的谓词。

      你将不得不面对的困难如下:

      • 处理术语之间的布尔关系(&amp;&amp;||
      • 处理嵌套布尔关系((a &amp;&amp; b) || c 不是 a &amp;&amp; (b || c)

      请注意,Predicate 有方便的 andor 方法来链接谓词。

      【讨论】:

        猜你喜欢
        • 2011-03-12
        • 1970-01-01
        • 2013-10-22
        • 1970-01-01
        • 2017-07-14
        • 1970-01-01
        • 2016-07-01
        • 2017-05-16
        • 2013-10-24
        相关资源
        最近更新 更多