Steam流

本文介绍了Java 8中新增的Stream流及其与Lambda表达式的结合使用,阐述了Stream流的概念、操作步骤,包括如何创建流、执行中间和终端操作。同时详细讲解了Lambda表达式的语法,如函数式接口、域运算符和Lambda体的构造。通过实例展示了Stream流在处理集合数据时的高效性和简洁性。


前言

提示:这里可以添加本文要记录的大概内容:

Steam流是java 8 版本新增的,配合同版本出现的Lambda表达式 ,给我们操作集合(Collection)提供了极大的便利。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Steam流是什么?

Java 中可以使用 java.util.Stream 对一个集合(实现了java.util.Collection接口的类)做各种操作,例如:求和、过滤、排序等等。这些操作可能是中间操作——返回一个 Stream 流,或者是终端操作——返回一个结果。
同时,流操作不会影响原来的集合,也不会存储数据,可以简单认为,流操作是把集合中的一个元素逐个复制放到一个首尾相接的流动的容器中进行相应的操作,操作结束,容器消失;下一次操作再重复上述过程,这也就是说Steam是延迟执行的。

Stream 流支持同步执行,也支持并发执行。如果我们直接获取 stream 流,得到的是同步执行的 stream 流;如果调用方法 parallelStream,则得到一个可以并发执行的 Stream 流。可以说Stream 流极大的提高开发效率,也可以使用它写出更加简洁明了的代码。

需要注意的是:Map不支持 Stream 流,但是它的 Key 和 Value 支持,因为它们实现了 Set 接口。

二、Lambda表达式

1.概述

lambda表达式是为了简写代码的写法,将这种写法叫为Lambda表达式。
lambda表达式核心概念为 函数式接口、:: 、-> 等基本语法,可以大大减少代码量的编写,使代码更加简练漂亮。
1、只有一个抽象函数的接口,就是函数式接口 ;
2、:: 可以称之为域运算符,主要是用来获取方法;
3、-> 的语法为 (变量或参数)->{代码体},是匿名函数的写法。也叫变量和代码的分隔符 ;
4、当只获取一个方法属性的时候 :: 和 -> 可以通用。

1.1 函数式接口

只有一个抽象方法的接口就是函数式接口

//定义一个函数式接口。只有一个抽象方法的接口就是函数式接口
public interface Lamb {
    void tastLamb();
}

2.Lambda具体表达语法

Lambda表达式在Java语言中的一个操作符"->",该操作符被称为Lambda操作符或箭头操作符,它将Lambda分为两个部分:

左侧:指定了Lambda表达式所需要的所有参数
  右侧:指定了Lambda体,即Lambda表达式所要执行的功能。

在函数式编程语言中,Lambda表达式的类型是函数。而在Java中,Lambda表达式是对象,它们必须依附于一类特别的对象类型——函数式接口(Functional Interface)。

2.1 Lambda常见表达示例

    //语法格式一:无参,无返回值,Lambda体只需要一条语句。
  Runnable r = () -> System.out.println("Hello Java Lambda!");
  
  //语法格式二:Lambda需要一个参数
  Consumer<String> con = (x) -> System.out.println(x);
  
  //语法格式三:Lambda只需要一个参数时,参数的小括号可以省略
    Consumer<String> con = x -> System.out.println(x);
     
  //语法格式四:Lambda需要两个参数,并且有返回值
    Comparator<Integer> com = (x, y) -> {
        System.out.println("函数式接口");
        return Integer.compare(x, y);
    };
    
  //语法格式五:当Lambda体只有一条语句时,return与大括号可以省略
    Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
  
  //语法格式六:数据类型可以省略,因为可由编译器推断得出,称为类型推断
    BinaryOperator<Long> operator = (Long x, Long y) -> {
       System.out.println("实现函数接口方法");
       return x + y;
    };

2.2 Lambda创建函数式接口实例

    //lambda表达式
  //如果使用lambda表达式来创建一个函数式接口实例,那这个lambda表达式的入参和返回必须符合这个函数式接口中唯一的抽象方法的定义
  list.forEach(item -> System.out.println(item));

三、Steam流操作步骤

  1. 创建Stream:使用一个数据源获取一个流
  2. 中间操作/中间操作链:对数据源进行处理(使用Lambda表达式比较方便,同时Stream流还有一些内置方法)
  3. 终止操作:执行中间操作,并产生结果

四、创建流的例子

  1. 由数组创建
    public static IntStream stream(int[] array)
    public static LongStream stream(long[] array)
    public static DoubleStream stream(double[] array)
    public static DoubleStream stream(double[] array)
  1. 由值创建
    对象.stream().中间操作.终止操作;

五、Stream流例子

假设我现在有一个Orange类,里面存放了橙子的颜色和重量

//Orange类
    private String color;
    private float weight;

    public Orange(){};
    public Orange(String color, float weight){
        this.color = color;
        this.weight =weight;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

    //重写toString方法为了正常显示

    @Override
    public String toString() {
        return "Orange{" +
                "color='" + color + '\'' +
                ", weight=" + weight +
                '}';
    }

    //重写equals、hashCode方法实现去重功能
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Orange orange = (Orange) o;
        return Float.compare(orange.weight, weight) == 0 &&
                Objects.equals(color, orange.color);
    }
    @Override
    public int hashCode() {
        return Objects.hash(color, weight);
    }
//测试类
 public static void main(String[] args) {
        //橙子
        List<Orange> oranges = Arrays.asList(
                new Orange("yellow",100),
                new Orange("green",150),
                new Orange("red",105),
                new Orange("yellow",90),
                new Orange("green",120),
                new Orange("red",60),
                new Orange("green",100),
                new Orange("green",70),
                new Orange("red",110),
                new Orange("yellow",150),
                new Orange("green",200),
                new Orange("red",60),
                new Orange("red",70),
                new Orange("red",70)
        );
        //1、过滤器filter()
        //挑选红色的橙子
        oranges.stream().filter(a -> a.getColor().equals("red")).forEach(System.out::println);
        System.out.println("----------------");

        //重量超过100的橙子
        oranges.stream().filter(a -> a.getWeight()>100).forEach(System.out::println);
        System.out.println("----------------");

        //重量大于100且为黄色橙子
        oranges.stream().filter(a -> a.getWeight()>100).filter(a->a.getColor().equals("yellow")).forEach(System.out::println);
        System.out.println("----------------");

        //2、去重distinct()
        //获得不同重量且不同颜色的橙子
        oranges.stream().distinct().forEach(System.out::println);
        System.out.println("----------------");

        //3、排序sorted()
        // 按颜色排序
        oranges.stream().sorted(Comparator.comparing(Orange::getColor)).forEach(System.out::println);
        System.out.println("----------------");

        //4、截断流limit()
        //只要前5个橙子
        oranges.stream().sorted(Comparator.comparing(Orange::getWeight).reversed()).sorted(Comparator.comparing(Orange::getColor)).limit(5).forEach(System.out::println);
        System.out.println("----------------");

        //5、跳过元素skip()
        //想要前五个中的后两个橙子
        oranges.stream()
                .sorted(Comparator.comparing(Orange::getWeight).reversed())
                .sorted(Comparator.comparing(Orange::getColor))
                .limit(5)
                .skip(3)
                .forEach(System.out::println);
        System.out.println("----------------");

        //6、函数传递map()
        //只想知道橙子有多少种颜色,不想知道重量
        oranges.stream()
                .map(Orange::getColor)
                .distinct()
                .forEach(System.out::println);
        System.out.println("----------------");

        //只想知道橙子有多少种颜色的大写,不想知道重量
        oranges.stream()
                .map(Orange::getColor)
                .map(String::toUpperCase)
                .distinct()
                .forEach(System.out::println);
        System.out.println("----------------");

        //7、判断是否存在anyMatch()
        Boolean g =  oranges.stream().anyMatch(a->a.getColor().equals("green"));
        System.out.println("green橙子存在? "+g);

        Boolean o =  oranges.stream().anyMatch(a->a.getColor().equals("orange"));
        System.out.println("orange橙子存在? "+o);
        System.out.println("----------------");

        //8、判断所有选中元素是否相同allMatch()
        Boolean g1 = oranges.stream().allMatch(a->a.getColor().equals("green"));
        System.out.println(g1);
        System.out.println("----------------");

        //9、是否没有匹配元素(当前元素是否不在集合中)noneMatch()
        Boolean g2 = oranges.stream().noneMatch(a->a.getColor().equals("green"));
        System.out.println(g2);
        Boolean b = oranges.stream().noneMatch(a->a.getColor().equals("blue"));
        System.out.println(b);
        System.out.println("----------------");

        //10、找到第一个元素与找到一个元素findFirst()与findAny();
        Optional<Orange> a = oranges.stream().findFirst();
        System.out.println(a);

        Optional<Orange>b1 = oranges.stream().findAny();
        System.out.println(b1);
        System.out.println("----------------");

        //11、统计流中元素个数count()
        long count = oranges.stream().count();
        System.out.println(count);
        System.out.println("----------------");

        //12、最大值与最小值max()与min()
        Optional<Float> optionalOrange = oranges.stream()
                .map(a1->a1.getWeight())
                .max(Float::compareTo);
        System.out.println(optionalOrange);

        Optional<Float> optionalOrange1 = oranges.stream()
                .map(a2->a2.getWeight())
                .min(Float::compareTo);
        System.out.println(optionalOrange1);
        System.out.println("----------------");

        //13、内部迭代forEach()
        oranges.stream()
                .map(Orange::getColor)
                .map(String::toUpperCase)
                .distinct()
                .forEach(System.out::println);
        System.out.println("----------------");

        //14、整合reduce()
        Optional<Float> optionalFloat = oranges.stream()
                .map(Orange::getWeight)
                .distinct()
                .reduce(Float::sum);
        System.out.println(optionalFloat);
        System.out.println("----------------");

    }

总结

本文章是学习总结练习笔记!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值