章十四、Java8Stream —— Stream、获取流、流操作

一、 Stream


        Stream 是 Java8 的新特性,它允许你以声明式的方式处理数据集合,可以把它看作是遍历数据集的高级迭代器。此外与 stream 与 lambada 表达示结合后编码效率与大大提高,并且可读性更强。

要澄清的是 java8 中的 stream 与 InputStream 和 OutputStream 是完全不同的概念

例:

public static void main(String[] args) {
    List<Apple> applestore = new ArrayList();
    applestore.add(new Apple(1,"red",500,"河南"));
    applestore.add(new Apple(2,"red",400,"陕西"));
    applestore.add(new Apple(3,"green",300,"上海"));
    applestore.add(new Apple(4,"green",200,"湖北"));
    applestore.add(new Apple(5,"green",100,"湖南"));
}

我们的需求是在 applestore 集合中找出红色苹果手机

使用 Stream 流快速实现操作

List<Apple> apples = applestore
    .stream()
    .filter(a -> a.getColor().equals("red"))
    .collect(Collectors.toList())

        这里使用的就是 Java8 中的 stream 流,使用的是声明性方式写的:说明想要完成什么(筛选,排序,取值),而不说明如何实现一个操作(for 循环)。同时可以将这些操作链接起来,达到一种流水线式的效果:

Java8 中的集合支持一个新的 Stream 方法,它会返回一个流。

什么是流呢?

简单的定义,就是“从支持数据处理操作的源,生成的元素序列”。

元素列表:和集合一样,流也提供了一个接口,访问特定元素类型的一组有序值。

数据源 :获取数据的源,比如集合。

数据处理操作 :流更偏向于数据处理和计算,比如 filter、map、find、sort 等。

        简单来说,我们通过一个集合的 stream 方法获取一个流,然后对流进行一系列流操作,最后再构建成我们需要的数据集合

语法:

stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|+
List<Integer> list =
    widgets.stream()
    .filter(b -> b.getColor() == RED)
    .sorted((x,y) -> x.getWeight() - y.getWeight())
    .sum();

二、 获取流


●  使用 Collection 接口下的 stream()

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();

  使用 Arrays 中的 stream() 方法,将数组转成流

Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);

  使用 Stream 中的静态方法:of()

Stream<Integer> stream = Stream.of(1,2,3,4,5,6);

  使用 BufferedReader.lines() 方法,将每行内容转成流

BufferedReader reader=new BufferedReader(new FileReader("stream.txt"));
Stream<String> lineStream = reader.lines();

三、 流操作


流操作可以分为两类:中间操作终端操作。回看之前的代码:

List<Apple> apples = applestore

        .stream() //获得流

        .filter(a -> a.getColor().equals("red")) //中间操作

        .collect(Collectors.toList()); //终端操作

简化一下就是:

        数据源 => 中间操作 => 终端操作 => 结果

        诸如 filter 或者 sort 等中间操作会返回另一个流,进而进行下一步流操作,而终

端操作则是将流关闭,构建新的数据集合对象(也可以不构建)。

  中间操作

filter:过滤流中的某些元素,

sorted(): 自然排序,流中元素需实现 Comparable 接口

distinct: 去除重复元素

limit(n): 获取 n 个元素

skip(n): 跳过 n 元素,配合 limit(n)可实现分页

map(): 将其映射成一个新的元素

import java.util.Arrays;

public class Demo2 {
    /*
    中间操作
    filter:过滤流中的某些元素,

    sorted(): 自然排序,流中元素需实现 Comparable 接口

    distinct: 去除重复元素

    limit(n): 获取 n 个元素

    skip(n): 跳过 n 元素,配合 limit(n)可实现分页

    map(): 将其映射成一个新的元素

     */
    public static void main(String[] args) {
        Integer[] array = new Integer[]{1,2,3,4,3,5};
        //long sum =  Arrays.stream(array).sorted().count();//链式调用

        //过滤
        Arrays.stream(array)
                .filter((e)->{
                    return e<5; //过滤(筛选得到)小于5的
                })
                .sorted((o1,o2)->{
                    return o2-o1; // 或降序排序
                }) //排序(默认是升序)
                .distinct() //去除重复元素
                .forEach((e)->{ //遍历
                    System.out.println(e);
                });
        Arrays.stream(array)
                .skip(4) //跳过4个元素
                .limit(2)//获取两个元素 如果不足,则只获取能获取的
                .forEach((e)->{
                    System.out.println(e);
                });
    }
}

  终端操作

forEach: 遍历流中的元素

toArray:将流中的元素倒入一个数组

Min:返回流中元素最小值

Max:返回流中元素最大值

count:返回流中元素的总个数

Reduce:所有元素求和

anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足条件则返回 true,否则返回 false

allMatch:接收一个 Predicate 函数,当流中每个元素都符合条件时才返回 true,否则返回 false

findFirst:返回流中第一个元素

collect:将流中的元素倒入一个集合,Collection 或 Map

import java.util.Arrays;
import java.util.Optional;

public class Demo3 {
    /*
    终端操作
    forEach: 遍历流中的元素
    toArray:将流中的元素倒入一个数组
    Min:返回流中元素最小值
    Max:返回流中元素最大值
    count:返回流中元素的总个数
    Reduce:所有元素求和
    anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足条件则返回 true,否则返回 false
    allMatch:接收一个 Predicate 函数,当流中每个元素都符合条件时才返回 true,否则返回 false
    findFirst:返回流中第一个元素
    collect:将流中的元素倒入一个集合,Collection 或 Map
     */
    public static void main(String[] args) {

        Integer[] array = new Integer[]{1,2,3,5,3,4,5};
        Integer max = Arrays.stream(array)
                .distinct() //去重
                .max((o1,o2)->{ //最大值
                    return o1-o2;
                }).get();
        System.out.println(max);

        Integer min = Arrays.stream(array)
                .distinct() //去重
                .min((o1,o2)->{ //最小值
                    return o1-o2;
                }).get();
        System.out.println(min);

        long count = Arrays.stream(array)
                .distinct()
                .count(); //统计元素个数
        System.out.println(count);

        long sum = Arrays.stream(array)
                .distinct()
                .reduce((a,b)->{return a+b;}).get(); //求和
        System.out.println(sum);

        boolean result1 = Arrays.stream(array)
                .distinct()
                .anyMatch((e)->{ // 只要有一个元素满足条件都返回true
                    return e>=2; //反之返回false
                });
        System.out.println(result1);

        boolean result2 = Arrays.stream(array)
                .distinct()
                .allMatch((e)->{ // 所有元素都满足条件返回true
                    return e>=2; //反之返回false
                });
        System.out.println(result2);


    }
}

对于类对象:

Student类

public class Student {
    private int num;
    private String name;
    private int age;

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student() {
    }

    public Student(int num, String name, int age) {
        this.num = num;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试类: 

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

public class Demo4 {
    public static void main(String[] args) {

        Student s1 = new Student(101,"张三1",18);
        Student s2 = new Student(102,"张三2",19);
        Student s3 = new Student(103,"张三3",20);
        Student s4 = new Student(104,"张三4",21);
        Student s5 = new Student(105,"张三5",22);

        ArrayList<Student> students = new ArrayList<>();
        students.add(s2);
        students.add(s3);
        students.add(s1);
        students.add(s5);
        students.add(s4);

        List<Student> students1 = students.stream()
                .distinct() // 去重
                .sorted((stu1,stu2)->{
                    return stu1.getNum()-stu2.getNum();
                })   //排序
                .collect(Collectors.toList()); //将流中的元素倒入一个集合
        System.out.println(students1);

        Object[] array = students.stream()
                .map(Student::getNum) //将getNum()方法传进去
                .toArray();
        System.out.println(Arrays.toString(array));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三木几

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值