JAVA8 Stream方法使用详解Filter、map等用法(一)

文章目录


流可以让我们从外部迭代转向内部迭代,流可以理解为按需加载(只有消费者消费的时候才开始生产),集合是供应商驱动(先把仓库装满,再开始卖)。流可以看作在时间中分布的一组,集合则是在空间中分布的一组。

 

以下例子都用此数据:

public class Dish {

    private final String name;

    private final boolean vegetarian;
    private final int calories;
    private final Type type;

    public Dish(String name, boolean vegetarian, int calories, Type type) {
        this.name = name;
        this.vegetarian = vegetarian;
        this.calories = calories;
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public boolean isVegetarian() {
        return vegetarian;
    }

    public int getCalories() {
        return calories;
    }

    public Type getType() {
        return type;
    }

    @Override
    public String toString() {
        return name;
    }
}
public enum Type {
    MEAT, FISH, OTHER
}
private static List<Dish> menu = Arrays.asList(
            new Dish("pork", false, 800, Type.MEAT),
            new Dish("beef", false, 700, Type.MEAT),
            new Dish("chicken", false, 400, Type.MEAT),
            new Dish("french fries", true, 530, Type.OTHER),
            new Dish("rice", true, 350, Type.OTHER),
            new Dish("season fruit", true, 120, Type.OTHER),
            new Dish("pizza", true, 550, Type.OTHER),
            new Dish("prawns", false, 300, Type.FISH),
            new Dish("salmon", false, 450, Type.FISH));

一、筛选和切片

用谓词来筛选各不相同的元素,或将流截断指定的长度

1、谓词筛选filter

Stream接口支持filter方法,该方法接受一个谓词(返回Boolean的函数)作为参数,例:

 public static void testFilter(){
        List<Dish> collect = menu.stream().filter(dish -> dish.isVegetarian()).collect(Collectors.toList());
        System.out.println(collect);
    }

2、筛选不同的元素distinct

distinct方法,返回一个元素各异的流,说白了就是去重。例:

public static void testDistinct() {
        List<String> strings = Arrays.asList("A", "B", "B", "C", "D", "D", "E");
        strings.stream().distinct().forEach(System.out::println);
    }

3、截断流limit

该方法会给定一个不超过指定长度,所需的长度作为参数传递给limit。例:

 public static void testLimit() {
        List<String> strings = Arrays.asList("A", "B", "B", "C", "D", "D", "E");
        List<String> collect = strings.stream().limit(3).collect(Collectors.toList());
        System.out.println(collect);
    }

4、跳过元素

流还支持跳过元素,返回扔掉前n个元素的流。例:

 public static void testSkip() {
        List<String> strings = Arrays.asList("A", "B", "B", "C", "D", "D", "E");
        List<String> collect = strings.stream().skip(3).collect(Collectors.toList());
        System.out.println(collect);
    }

二、映射

一个非常常见的数据处理就是从某些对象种选择信息,比如在SQL里,你可以从表中选择一列,Stream API也通过map和flatMap提供了类似的方法

1、map对每个元素应用函数

流支持map方法,它接受一个函数作为参数。这个函数会被应用到每个元素上,并映射成新的元素。说白了就是返回一个新的l类型的list集合。例:

map返回的是Stream(String)

public static void testMap() {
        List<String> collect = menu.stream().map(Dish::getName).collect(Collectors.toList());
        System.out.println(collect);
    }
  • 2、流的扁平化

flatMap各个数组并不是分别映射成一个流,而是映射成流的内容,说白了就是把几个小的list转换到一个大的list。例:

public static void testFlatMap() {
        String[] array = {"HELLO","WORLD"};
        Stream<String> stream = Arrays.stream(array);
        stream.forEach(System.out::println);
        List<String> strings = Arrays.asList("hello", "world");
        List<String[]> collect = strings.stream().map(w -> w.split("")).collect(Collectors.toList());
        System.out.println(collect);
        Stream<Stream<String>> streamStream = collect.stream().map(array1 -> Arrays.stream(array1));
        List<Stream<String>> collect1 = collect.stream().map(array1 -> Arrays.stream(array1)).collect(Collectors.toList());
        collect1.stream().forEach(d -> {
            d.forEach(System.out::println);
        });
        System.out.println(collect1);
        Stream<String> stringStream = strings.stream().map(w -> w.split("")).flatMap(Arrays::stream);
        List<String> collect2 = strings.stream().map(w -> w.split("")).flatMap(Arrays::stream).collect(Collectors.toList());
        System.out.println(collect2);
    }
  •  

在这里插入图片描述
给定数字列表1[1,2,3]和列表2[3,4],返回[(1,3),(2,3),(2,3),(2,4),(3,3),(3,4)]

List<Integer> integers = Arrays.asList(1, 2, 3);
List<Integer> integers1 = Arrays.asList(3, 4)
 List<int[]> collect3 = integers.stream().flatMap(i -> integers1.stream()
                .map(j -> new int[]{i, j})).collect(Collectors.toList());
 System.out.println(collect3);

三、查找和匹配

另一个常见的数据处理套路是看着数据集中的某些元素是否匹配一个给定属性。
allMatch,、anyMatch、noneMatch、findFirst、findAny

1、至少匹配一个

anyMatch是否有一个元素匹配

if (menu.stream().anyMatch(Dish::isVegetarian))  {
            System.out.println("");
        }

2、匹配所有

allMatch匹配所有

menu.stream().allMatch(d -> d.getCalories < 1000);
  •  

noneMatch和allMatch是相对的没有一个元素匹配

3、查找元素

findAny返回当前流任意元素

 public static void testFindAny() {
        Optional<Dish> collect = menu.stream().filter(dish -> dish.getCalories() > 1000).findAny();
        System.out.println(collect);
    }

返回值是一个Optional,是一个容器代表值存在不存在,这个类我们将在以后章节中详细讲解。

4、查找第一个元素

findFirst

 public static void testFindAny() {
        Optional<Dish> collect = menu.stream().filter(dish -> dish.getCalories() > 1000).findFrist();
        System.out.println(collect);
    }

以上是部分API,我们下一章节继续讲解。

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Java StreamJava 8 中新增的一个 API,用于处理集合数据。它提供了一种更加简洁、高效的方式来操作集合,可以让代码更加简洁、易读、易维护。下面是 Java Stream 的基本使用方法: 1. 创建流 Java Stream 可以从多种数据源中创建,比如集合、数组、文件等。例如,从集合创建一个 Stream 可以使用以下代码: ```java List<String> list = new ArrayList<>(); Stream<String> stream = list.stream(); ``` 2. 中间操作 中间操作是指对 Stream 进行操作,返回一个新的 Stream。常见的中间操作包括:filtermap、sorted、distinct 等。例如,下面的代码使用 filter 操作过滤出长度大于 5 的字符串: ```java List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); Stream<String> stream = list.stream().filter(s -> s.length() > 5); ``` 3. 终止操作 终止操作是指对 Stream 进行最终的操作,返回一个非 Stream 的结果。常见的终止操作包括:forEach、reduce、collect、count 等。例如,下面的代码使用 forEach 操作输出过滤后的字符串: ```java List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); list.stream().filter(s -> s.length() > 5).forEach(System.out::println); ``` 4. 短路操作 短路操作是指对 Stream 进行操作时,只要满足一定条件就可以停止操作,不必对整个流进行操作。常见的短路操作包括:findFirst、findAny、allMatch、anyMatch、noneMatch 等。例如,下面的代码使用 findAny 操作找到第一个长度大于 5 的字符串: ```java List<String> list = Arrays.asList("apple", "banana", "orange", "watermelon"); Optional<String> result = list.stream().filter(s -> s.length() > 5).findAny(); ``` 以上就是 Java Stream 的基本使用方法,需要注意的是,Stream 是一次性的,一旦进行了终止操作,就不能再对该 Stream 进行操作。同时,Stream 也是惰性求值的,只有在终止操作时才会进行真正的计算。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值