初始化并链接谓词

huangapple go评论70阅读模式
英文:

Initalize and chain predicate

问题

以下是翻译好的内容:

我有一个如下所示的人员类:

class Person {
       String sex;
       boolean mastersDegree;
       String position;
       //一些其他字段
       //getters, setters, 构造函数, toString ...
    }

我需要根据运行时的布尔变量来过滤人员列表,而不提前知道过滤条件。我会通过一些布尔变量在运行时获得这些条件:

boolean isMale = false;
boolean isDeveloper = false;
boolean hasMaster = true;

我想使用 Predicate 并根据布尔值需要进行链式操作。只有 true 值应该用于创建过滤 Predicate,即如果全部为 false,则不应该对列表进行过滤。目前,我是这样做的:

List<Person> persons = ...

Predicate<Person> filter = null;

if (isMale)
    filter = x -> x.getSex().equals("M");
if (isDeveloper)
    filter = filter.and(x -> x.getPosition().equals("DEV"));
if (hasMaster)
   filter = filter.and(Person::hasAMastersDegree);

persons.stream().filter(filter).forEach(System.out::println);

上述方法存在一个问题:它只在满足第一个 if 条件且我首先将 predicate 初始化为 null 时才起作用。否则,我会得到 NPE 或 "variable filter might haven't been initialized"。我查看了 Predicate 类,希望能找到一些静态值,类似于 Predicate.TRUE,它接受每个项或根本不进行过滤,但没有成功。如果可能的话,我想避免这种情况:

if(isMale && filter != null)

我该如何做?

Predicate<Person> filter = ???;
英文:

I have a person class as follows:

class Person {
       String sex;
       boolean mastersDegree;
       String position;
       //some more fields
       //getters, setters, const. toString ..
    }

I have to filter a list of persons without knowing the filter criteria before hand. I'll get those at run time through some boolean variables

boolean isMale = false;
boolean isDeveloper = false;
boolean hasMaster = true;

I want to use a predicate and chain them if needed according to the boolean values. Only true values should be used to create the filter predicate, i.e if all are false the list should not be filterd at all. For now I am doing it like

List&lt;Person&gt; persons = ...

Predicate&lt;Person&gt; filter = null;

if (isMale)
    filter = x -&gt; x.getSex().equals(&quot;M&quot;);
if (isDeveloper)
    filter = filter.and(x -&gt; x.getPosition().equals(&quot;DEV&quot;));
if (hasMaster)
   filter = filter.and(Person::hasAMastersDegree);

persons.stream().filter(filter).forEach(System.out::println);

The above has one issue: it only works if the first if condition is met and I intialize the predicate with null first. Otherwise I will get a NPE or "variable filter might haven't been initialized". I have looked into the predicate class hoping to find some static value something like Predicate.TRUE which accepts every item or dosent filter at all but with no luck. I want to avoid this if possible:

if(isMale &amp;&amp; filter != null)

How can I do so?

Predicate&lt;Person&gt; filter = ???;

答案1

得分: 2

你可以使用以下代码进行初始化:

Predicate<Person> filter = p -> true;
英文:

You can initialise it with

Predicate&lt;Person&gt; filter = p -&gt; true;

huangapple
  • 本文由 发表于 2020年9月29日 23:22:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64122678.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定