如何有条件地替换Collection中的值,例如replaceIf(Predicate<T>)?

Posted

技术标签:

【中文标题】如何有条件地替换Collection中的值,例如replaceIf(Predicate<T>)?【英文标题】:How to replace a value conditionally in a Collection, such as replaceIf(Predicate<T>)? 【发布时间】:2016-06-18 21:11:20 【问题描述】:

如果 List 或 Collection 的值为 null,我们有什么简单的方法可以替换该值?

我们总是可以使用list.stream().filter(Objects::nonNull); 并可能将 0 添加回列表中。

但我正在寻找像 list.replaceIf(Predicate&lt;&gt;) 这样的 API。

【问题讨论】:

【参考方案1】:

这仅适用于List,不适用于Collection,因为后者没有替换或设置元素的概念。

但是给定一个List,使用List.replaceAll() 方法很容易做你想做的事:

List<String> list = Arrays.asList("a", "b", null, "c", "d", null);
list.replaceAll(s -> s == null ? "x" : s);
System.out.println(list);

输出:

[a, b, x, c, d, x]

如果你想要一个带有谓词的变体,你可以编写一个小辅助函数来做到这一点:

static <T> void replaceIf(List<T> list, Predicate<? super T> pred, UnaryOperator<T> op) 
    list.replaceAll(t -> pred.test(t) ? op.apply(t) : t);

这将被如下调用:

replaceIf(list, Objects::isNull, s -> "x");

给出相同的结果。

【讨论】:

感谢 Stuart 更正了这个问题,并给出了一个简洁优雅的答案。【参考方案2】:

你需要一个简单的地图函数:

Arrays.asList( new Integer[] 1, 2, 3, 4, null, 5 )
.stream()
.map(i -> i != null ? i : 0)
.forEach(System.out::println); //will print: 1 2 3 4 0 5, each on a new line

【讨论】:

【参考方案3】:

试试这个。

public static <T> void replaceIf(List<T> list, Predicate<T> predicate, T replacement) 
    for (int i = 0; i < list.size(); ++i)
        if (predicate.test(list.get(i)))
            list.set(i, replacement);

List<String> list = Arrays.asList("a", "b", "c");
replaceIf(list, x -> x.equals("b"), "B");
System.out.println(list);
// -> [a, B, c]

【讨论】:

【参考方案4】:

这可以试试这个:

list.removeAll(Collections.singleton(null));  

【讨论】:

他想替换它们而不是删除它们

以上是关于如何有条件地替换Collection中的值,例如replaceIf(Predicate<T>)?的主要内容,如果未能解决你的问题,请参考以下文章

有条件地替换 SELECT 中的值

使用 R 中的条件替换列中的值

使用 dplyr 有条件地替换列中的值

使用 dplyr [重复] 有条件地将一列中的值替换为另一列中的值

如何在pySpark中有条件地替换值并将替换后的值用于下一个条件

用 D 列中的值有条件地替换 A、B、C 列中的值