# Java 流过滤器

原文：http://zetcode.com/java/streamfilter/

Java 流过滤器教程展示了如何使用过滤操作过滤 Java 流。

## Java 流

Java 流是来自源的支持聚合操作的一系列元素。 流不存储元素。 元素是按需计算的。 元素是从数据源（如集合，数组或 I/O 资源）中消耗的。

流聚合操作类似于 SQL 操作。 我们可以对流应用过滤，映射，缩小，匹配，搜索或排序操作。 流允许链接多个流操作。 与使用外部迭代的集合不同，流在内部进行迭代。

## Java 流过滤器

Java 流过滤器方法是一个中间操作，它返回与给定谓词匹配的流元素。 谓词是一个返回布尔值的函数。

## Java 流过滤器字符串长度

下面的示例过滤字符串列表。

`JavaStreamFilterStringLength.java`

```java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JavaStreamFilterStringLength {

    public static void main(String[] args) {

        List<String> words = Arrays.asList("pen", "custom", "orphanage",
                "forest", "bubble", "butterfly");

        List<String> result = words.stream().filter(word -> word.length() > 5)
                .collect(Collectors.toList());

        result.forEach(word -> System.out.println(word));
    }
}

```

我们有一个单词表。 我们过滤列表以仅包括长度大于 5 的字符串。

```java
List<String> result = words.stream().filter(word -> word.length() > 5)
        .collect(Collectors.toList());

```

使用`stream()`方法，我们从字符串列表创建 Java 流。 在此流上，我们应用`filter()`方法。 `filter()`方法接受匿名函数，该函数对长度大于 5 的流的所有元素返回布尔值`true`。 我们使用`collect()`方法从流中创建一个列表。

```java
result.forEach(word -> System.out.println(word));

```

我们使用`forEach()`方法遍历结果并将其所有元素打印到控制台。

```java
custom
orphanage
forest
bubble
butterfly

```

这些单词有五个以上的字符。

## Java 流过滤器空值

下一个示例过滤掉`null`值。

`JavaStreamFilterRemoveNulls.java`

```java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JavaStreamFilterRemoveNulls {

    public static void main(String[] args) {

        List<String> words = Arrays.asList("cup", null, "forest",
                "sky", "book", null, "theatre");

        List<String> result = words.stream().filter(w -> w != null)
                .collect(Collectors.toList());

        System.out.println(result);
    }
}

```

我们有一个单词表。 通过流过滤操作，我们创建了一个新列表，其中删除了`null`值。

```java
List<String> result = words.stream().filter(w -> w != null)
        .collect(Collectors.toList());

```

在 lambda 表达式的主体中，我们检查值是否不是`null`。 `collect()`方法是一种终端操作，可从过滤后的流中创建列表。

```java
[cup, forest, sky, book, theatre]

```

最终输出中没有`null`值。

## Java 流多个过滤器操作

可以对流应用多个过滤器操作。

`JavaStreamMultipleFilters.java`

```java
package com.zetcode;

import java.util.Arrays;
import java.util.function.IntConsumer;

public class JavaStreamMultipleFilters {

    public static void main(String[] args) {

        int[] inums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

        IntConsumer icons = i -> System.out.print(i + " ");

        Arrays.stream(inums).filter(e -> e < 6 || e > 10)
                .filter(e -> e % 2 == 0).forEach(icons);
    }
}

```

在示例中，我们对整数流应用了多个过滤操作。

```java
int[] inums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

```

我们有一个整数值数组。

```java
IntConsumer icons = i -> System.out.print(i + " ");

```

`IntConsumer`是一个接受单个整数值参数且不返回结果的操作。

```java
Arrays.stream(inums).filter(e -> e < 6 || e > 10)
        .filter(e -> e % 2 == 0).forEach(icons);

```

使用`Arrays.stream()`方法从数组创建流。 执行多个过滤操作。

```java
2 4 12 14 

```

这些整数满足所有过滤条件。

## Java 流过滤器对象

下一个示例显示了如何过滤对象。

`User.java`

```java
package com.zetcode;

public class User {

    private String name;
    private String email;

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

```

在示例中，我们使用此`User`类。

`JavaStreamFilterObjects.java`

```java
package com.zetcode;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JavaStreamFilterObjects {

    public static void main(String[] args) {

        List<User> persons = Arrays.asList(
                new User("Jack", "jack234@gmail.com"),
                new User("Peter", "pete2@post.com"),
                new User("Lucy", "lucy17@gmail.com"),
                new User("Robert", "bob56@post.com"),
                new User("Martin", "mato4@imail.com")
        );

        List<User> result = persons.stream()
                .filter(person -> person.getEmail().matches(".*post\\.com"))
                .collect(Collectors.toList());

        result.forEach(p -> System.out.println(p.getName()));
    }
}

```

该示例创建`User`对象的流。 它过滤与特定正则表达式匹配的那些。

```java
List<User> result = persons.stream()
        .filter(person -> person.getEmail().matches(".*post\\.com"))
        .collect(Collectors.toList());

```

在过滤谓词中，我们选择与`.*post\\.com`模式匹配的电子邮件。

```java
Peter
Robert

```

这两个用户的电子邮件与常规模式匹配。

## Java 流过滤器按键映射

在以下示例中，我们通过映射的键过滤映射。

`JavaStreamFilterMapByValues.java`

```java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;

public class JavaStreamFilterMapByKeys {

    public static void main(String[] args) {

        Map<String, String> hmap = new HashMap<>();

        hmap.put("de", "Germany");
        hmap.put("hu", "Hungary");
        hmap.put("sk", "Slovakia");
        hmap.put("si", "Slovenia");
        hmap.put("so", "Somalia");
        hmap.put("us", "United States");
        hmap.put("ru", "Russia");

        hmap.entrySet().stream().filter(map -> map.getKey().startsWith("s"))
                .forEach(m -> System.out.println(m));
    }
}

```

该示例过滤以`s`字母开头的域名。

```java
si=Slovenia
sk=Slovakia
so=Somalia

```

这是示例的输出。

## Java 流过滤器按值映射

在以下示例中，我们根据映射的值过滤映射。

`JavaStreamFilterMapByValues.java`

```java
package com.zetcode;

import java.util.HashMap;
import java.util.Map;

public class JavaStreamFilterMapByValues {

    public static void main(String[] args) {

        Map<String, String> hmap = new HashMap<>();

        hmap.put("de", "Germany");
        hmap.put("hu", "Hungary");
        hmap.put("sk", "Slovakia");
        hmap.put("si", "Slovenia");
        hmap.put("so", "Somalia");
        hmap.put("us", "United States");
        hmap.put("ru", "Russia");

        hmap.entrySet().stream().filter(map -> map.getValue().equals("Slovakia")
                || map.getValue().equals("Slovenia"))
                .forEach(m -> System.out.println(m));
    }
}

```

在示例中，我们从映射中过滤出两个国家。

```java
si=Slovenia
sk=Slovakia

```

这是输出。

在本教程中，我们已经处理过 Java 流过滤操作。 您可能也对相关教程感兴趣： [Java 流](/lang/java/streams/)，[Java 流归约](/java/streamreduce/)，[Java 流映射](/java/streammap/)，[Java8 `forEach`教程](/articles/java8foreach/)，和[用 Java 过滤列表](/articles/javafilterlist/)。