如何动态地将 Predicate 添加到 List 中

3

有没有办法在Java中动态地向List中添加Predicate?简单来说,我是这样做的:

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()
);

1
这是因为您需要将两个“Predicate”应用于某些输入吗? - Eugene
是的。实际上我想稍后将它们合并。实现比这复杂得多。它用于一个类中,该类用于其他类,并且不同的调用类将拥有自己的一组过滤器。 - Habib Rosyad
4个回答

8

解决方案:

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

解释:

Arrays.asList 返回一个固定长度的列表1,用于包装数组参数。由于它是固定大小的,会改变大小的方法将抛出 UnsupportedOperationException 异常。

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


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


我没有注意到。非常感谢,现在可以工作了。 - Habib Rosyad

2

Arrays.asList()方法返回一个固定大小的List实例:

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

它更像是一种“快捷方式”,用于手动编写一系列事物的列表。确切地说,是一份“固定大小”的事物列表。这意味着您可以“替换”元素,但不能添加或删除条目。

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


2
问题在于,Arrays.asList 方法创建的是固定大小的列表:你无法向使用此方法获取的列表添加元素。
你需要创建一个可变的 List,例如使用 new ArrayList():
List<Predicate<String>> filters = new ArrayList<>(Arrays.asList(
  t -> !Utilities.isNumeric(t)
));
filters.add(t -> !t.isEmpty());

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


2

如果需要将两个Predicate应用于某个输入,可以将它们链接在一起。唯一的缺点是需要进行大量的强制类型转换——因为lambda表达式和方法引用是多态表达式...

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

我仍在学习Java 8,顺便说一下,这是很好的信息。实际上,最终我想要将所有过滤器组合起来,我使用了compositeFilter = filters.stream().reduce(f -> true, Predicate::and) - Habib Rosyad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接