Operating on and Removing an Item from Stream – 操作并从流中删除一个项目

最后修改: 2018年 9月 30日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll learn about the various ways in which we can operate on an item in a Java 8 stream and then remove it once the operation is complete.

在这个快速教程中,我们将了解对Java 8流中的一个项目进行操作的各种方法,然后在操作完成后将其删除。

2. Setup

2.设置

Let us define our Item object first. This is a simple object with a single int field.

让我们首先定义我们的Item对象。这是一个简单的对象,只有一个int字段。

It has a method that determines whether the object is qualified for operation, based on the internal value:

它有一个方法,根据内部值确定该对象是否有资格进行操作。

class Item {
    private int value;

    // constructors

    public boolean isQualified() {
        return value % 2 == 0;
    }

    public void operate() {
        System.out.println("Even Number");
    }
}

Now we can create a source for our Stream which can be a collection of Items:

现在我们可以为我们的Stream创建一个源,它可以是一个Items:的集合。

List<Item> itemList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    itemList.add(new Item(i));
}

3. Filtering Items

3.筛选项目

In many cases, if we want to do something with a subset of items, we can use the Stream#filter method, and we don’t need to remove anything first:

在许多情况下,如果我们想对一个子集的项目做些什么,我们可以使用Stream#filter方法,我们不需要先删除任何东西:

itemList.stream()
  .filter(item -> item.isQualified())
  ...

4. Operating and Removing an Item

4.操作和拆除一个项目

4.1. Collection.removeIf

4.1.Collection.removeIf

We can use Streams to iterate and operate over the collection of Items.

我们可以使用Streams来对Items的集合进行迭代和操作。

Using Streams, we can apply lambda functions known as Predicates. To read more about Streams and Predicates, we have another article here.

使用Streams,我们可以应用被称为Predicates的lambda函数。要阅读更多关于StreamsPredicates的内容,我们有另一篇文章这里

We can create a Predicate that would determine if an Item qualifies to be operated on:

我们可以创建一个Predicate来确定一个Item是否有资格被操作。

Predicate<Item> isQualified = item -> item.isQualified();

Our Predicate will filter the Items that we want to operate on:

我们的Predicate将过滤我们要操作的Items

itemList.stream()
  .filter(isQualified)
  .forEach(item -> item.operate());

Once we’ve finished operating on the items in the stream, we can remove them using the same Predicate we used earlier for filtering:

一旦我们完成了对流中项目的操作,我们就可以使用先前用于过滤的同一个Predicate来删除它们。

itemList.removeIf(isQualified);

Internally, removeIf uses an Iterator to iterate over the list and match the elements using the predicate. We can now remove any matching elements from the list.

在内部,removeIf使用一个Iterator来迭代列表并使用谓词来匹配元素。我们现在可以从列表中删除任何匹配元素。

4.2. Collection.removeAll

4.2.Collection.removeAll

We can also use another list to hold the elements that have been operated upon, and then remove them from the original list:

我们也可以用另一个列表来保存被操作过的元素,然后从原来的列表中删除它们。

List<Item> operatedList = new ArrayList<>();
itemList.stream()
  .filter(item -> item.isQualified())
  .forEach(item -> {
    item.operate();
    operatedList.add(item);
});
itemList.removeAll(operatedList);

Unlike removeIf that uses an Iterator, removeAll uses a simple for-loop to remove all the matching elements in the list.

与使用迭代器的removeIf不同,removeAll使用一个简单的for-loop来移除列表中所有匹配的元素。

5. Conclusion

5.总结

In this article, we looked at a way of operating on an item in Java 8 Streams and then removing it. We also saw a way of doing it by using an additional list and removing all the matched elements.

在这篇文章中,我们看了一种在Java 8 Streams中对一个项目进行操作,然后将其删除的方法。我们还看到了一种通过使用一个额外的列表并删除所有匹配元素的方法。

The source code for this tutorial and the relevant test cases are available over on GitHub.

本教程的源代码和相关的测试案例可在GitHub上获取。