如何动态地将谓词添加到列表中

时间:2017-08-22 07:55:30

标签: java list java-8 predicate

有没有办法在Java中动态地将Predicate添加到List中?为了简单说明,我已经这样做了:

List<Predicate<String>> filters = Arrays.asList(
    t -> !Utilities.isNumeric(t)
);
filters.add(t -> !t.isEmpty());

但执行filters.add会导致UnsupportedOperationException。像这样的固定列表很好。

List<Predicate<String>> filters = Arrays.asList(
    t -> !Utilities.isNumeric(t),
    t -> !t.isEmpty()
);

4 个答案:

答案 0 :(得分:7)

解决方案:

List<Predicate<String>> filters = new ArrayList<>(Arrays.asList(
    t -> !Utilities.isNumeric(t)
));

说明:

Arrays.asList返回数组参数的固定长度列表 1 包装器。由于它是固定大小的,因此会改变大小的方法抛出UnsupportedOperationException

通过将其提供给ArrayList构造函数,您可以创建一个新列表,其大小可以更改。

1 - ....但是列表不可变。可以通过更新后备阵列或使用List::set(int, T)方法来修改它。

答案 1 :(得分:2)

这里的问题是Arrays.asList创建了一个固定大小的列表:您无法添加到使用此方法获得的列表。

您必须创建一个可变列表,例如使用new ArrayList()

List<Predicate<String>> filters = new ArrayList<>(Arrays.asList(
  t -> !Utilities.isNumeric(t)
));
filters.add(t -> !t.isEmpty());

将起作用,因为filters列表是可变的。

答案 2 :(得分:2)

Arrays.asList()会返回List的已修复实例:

  

返回由指定数组支持的固定大小的列表。

它的意思是&#34;捷径&#34;当你&#34;手动&#34;写下一份事情清单。 A&#34;固定大小&#34;事情清单要准确。这意味着你可以替换&#34;元素,但不添加或删除条目。

因此,只需将该调用的结果用作创建另一个列表的输入,例如:new ArrayList<>(Arrays.asList(...)

答案 3 :(得分:2)

如果您需要将两个 Predicate应用于某些输入,您可以将它们链接起来。涉及大量转换的唯一缺点是 - 因为lambda表达式和方法引用是多义表达式......

Predicate<String> both = ((Predicate<String>) Utilities::isNumeric).negate()
                             .and(((Predicate<String>) String::isEmpty).negate());