簡體   English   中英

使用Java lambda的外部可配置過濾

[英]Externally configurable filtering using Java lambdas

假設我有一個外部JSON:

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

這意味着我想在名為"jack"age > 25人的Person對象列表中進行檢查。 使用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對象列表。

據我所知,這與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"));

從而鏈接你的謂詞

這有兩種方法。

您可以直接串聯調用所需的過濾器:

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

或者,您有自己的類實現Predicate<Person>

在這種情況下,您可以使用構建器模式逐步構建謂詞。

您將面臨的困難如下:

  • 處理術語之間的布爾關系( && vs ||
  • 處理嵌套的布爾關系( (a && b) || c不是a && (b || c)

請注意, Predicate具有鏈接謂詞的方便and / or方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM