java Stream详解

Stream的执行流程可分为:Stream的创建 -> 一些列的中间操作(过滤,映射等) -> 终止操作
1.Stream的创建方式

package com.yl.pdfdemo.day08.p8;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description Stream
 * @Version 1.0
 */

public class StreamAPITest {
    /**
     * Stream关注的是对数据的计算,主要和cpu打交道
     * 集合主要是存储数据,与内存打交道
     *
     *  Stream的 执行流程
     *  1.Stream的实例化
     *  2.一些列的中间操作(过滤,映射等)
     *  3.终止操作
     *
     */

    //创建Stream的方式一: 通过集合
    @Test
    public void test1() {
        //返回一个顺序流
        //default Stream<E> stream()
        List<String> list = Arrays.asList("a", "b", "c", "d");
        Stream<String> stream1 = list.stream();
        //返回一个并行流
        //default Stream<E> parallelStream()
        Stream<String> stream2 = list.parallelStream();
    }

    //创建Stream的方式二: 通过数组
    @Test
    public void test2() {
        int[] arr = new int[]{11,22,33};
        IntStream stream = Arrays.stream(arr);

        Person p1 = new Person(1001,"xioabai",18);
        Person p2 = new Person(1002,"xioahei",18);
        Person[] persons = new Person[]{p1,p2};
        Stream<Person> personStream = Arrays.stream(persons);
    }

    //创建Stream的方式三: 通过Stream的of()
    @Test
    public void test3() {
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    }

    //创建Stream的方式四: 创建无限流
    @Test
    public void test4() {
        //迭代
        //遍历前10个偶数
        Stream.iterate(0,t -> t + 2).limit(10).forEach(System.out::println);

        //生成
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }
}

2.用到的实体类

package com.yl.pdfdemo.day08.p8;

import java.util.Objects;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description
 * @Version 1.0
 */

public class Person {
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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 Person() {
    }

    public Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return id == person.id &&
                age == person.age &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, age);
    }
}

3.Stream的中间操作

package com.yl.pdfdemo.day08.p8;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description Stream中间操作
 * @Version 1.0
 */

public class StreamAPITest1 {

    public List<Person> getPersonList() {
        Person p1 = new Person(1001,"xiaohei",17);
        Person p2 = new Person(1002,"xiaobai",18);
        Person p3 = new Person(1003,"xiaolon",20);
        Person p4 = new Person(1004,"dahei",22);
        Person p5 = new Person(1005,"dabai",17);
        Person p6 = new Person(1006,"lilan",23);
        Person p7 = new Person(1007,"lisiu",25);
        List<Person> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        list.add(p6);
        list.add(p7);
        return list;
    }

    //1.筛选与切片
    @Test
    public void test1() {
        List<Person> list = getPersonList();
        //filter(Predicate) 从流中排除某些元素
        //筛选年龄大于20的
        list.stream().filter(p -> p.getAge() > 20).forEach(System.out::println);
        System.out.println();

        //limit(n)截断流,使其元素不超过给定数量
        list.stream().limit(3).forEach(System.out::println);
        System.out.println();

        //skip(n) -跳过元素,返回一个扔掉了前n个元素的流
        list.stream().skip(2).forEach(System.out::println);
        System.out.println();

        //distinct() -筛选,根据流中元素的hashcode()和equals()方法去重
        list.add(new Person(1008,"xxl",25));
        list.add(new Person(1008,"xxl",25));
        list.add(new Person(1008,"xxl",25));
        list.stream().distinct().forEach(System.out::println);
    }

    //映射
    @Test
    public void test2() {
        //map(Function f) 接收一个函数作为参数,将元素转换成其他形式或者提取信息
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd", "ee");
        list.stream().map(s -> s.toUpperCase()).forEach(System.out::println);

        List<Person> personList = getPersonList();
        //获取年龄小于20的name
        personList.stream().filter(p -> p.getAge() < 20).map(Person::getName).forEach(System.out::println);

        //flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另外一个流,然后把所有流连接成一个流
        list.stream().flatMap(StreamAPITest1::changeStringToStream).forEach(System.out::println);

    }

    public static Stream<Character> changeStringToStream(String str) {
        ArrayList<Character> lsit = new ArrayList<>();
        for (Character c : str.toCharArray()) {
            lsit.add(c);
        }
        return lsit.stream();
    }

    //排序
    @Test
    public void test3() {
        //sorted() -自然排序
        List<Integer> list = Arrays.asList(10, 8, 90, 100, 19);
        list.stream().sorted().forEach(System.out::println);

        //sorted(Comparator com) -定制排序
        List<Person> personList = getPersonList();
        personList.add(new Person(1001,"xxl",25));
        //先按照id从大到小排序,再按照年龄从小到大排序
        personList.stream().sorted((p1,p2) -> {
            int value = -Integer.compare(p1.getId(),p2.getId());
            if (value != 0) {
                return value;
            } else {
                return Integer.compare(p1.getAge(),p2.getAge());
            }
        }).forEach(System.out::println);
    }
}

4.Stream的终止操作

package com.yl.pdfdemo.day08.p8;

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description Stream的终止操作
 * @Version 1.0
 */

public class StreamAPITest2 {
    public List<Person> getPersonList() {
        Person p1 = new Person(1001,"xiaohei",17);
        Person p2 = new Person(1002,"xiaobai",18);
        Person p3 = new Person(1003,"xiaolon",20);
        Person p4 = new Person(1004,"dahei",22);
        Person p5 = new Person(1005,"dabai",17);
        Person p6 = new Person(1006,"lilan",23);
        Person p7 = new Person(1007,"lisiu",25);
        List<Person> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        list.add(p5);
        list.add(p6);
        list.add(p7);
        return list;
    }
    //1.匹配与查找
    @Test
    public void test1() {
        List<Person> list = getPersonList();
        //allMatch(Predicate p) -检查是否匹配所有元素
        //判断集合中所有带飞元素年龄是否都大于20
        boolean b = list.stream().allMatch(p -> p.getAge() > 20);
        System.out.println(b); //false

        //anyMatch(Predicate p) -检查是否至少匹配一个元素
        //是否存在年龄小于18
        boolean b1 = list.stream().anyMatch(p -> p.getAge() < 18);
        System.out.println(b1); //true

        //noneMatch(Predicate p) -检查是否没有匹配的元素
        boolean b2 = list.stream().noneMatch(p -> p.getAge() > 50);
        System.out.println(b2); //true

        //findFirst -返回第一个元素
        Optional<Person> person = list.stream().findFirst();
        System.out.println(person);//Optional[Person{id=1001, name='xiaohei', age=17}]

        //findAny -返回流中任意一个元素
        Optional<Person> person1 = list.parallelStream().findAny();
        System.out.println(person1);//Optional[Person{id=1005, name='dabai', age=17}]

        //count -返回流中元素的总个数
        long count = list.stream().count();
        System.out.println(count);//7

        //max(Comparator com) -返回流中最大的值
        //获取最大的年龄
        Stream<Integer> stream = list.stream().map(p -> p.getAge());
        Optional<Integer> max = stream.max(Integer::compareTo);
        System.out.println(max.isPresent());// true 判断Optional内是否包含对象
        System.out.println(max); //Optional[25]
        System.out.println(max.get());//25

        //min(Comparator com) -返回流中最小的值
        //获取年龄最小的person
        Optional<Person> min = list.stream().min((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
        System.out.println(min);//Optional[Person{id=1001, name='xiaohei', age=17}]

        //forEach(Consumer c) - 内部迭代
        list.stream().forEach(System.out::println);

    }

    //归约
    @Test
    public void test2() {
        //reduce(T identity,BinaryOperator) -将流中元素反复结合起来,得到一个值,返回T
        //比如1-10的和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        //第一个参数为初始值
        Integer sum = list.stream().reduce(0, Integer::sum);
        System.out.println(sum);//55

        //reduce(BinaryOperator) -将流中元素反复结合起来,得到一个值,返回Optional<T>
        List<Person> personList = getPersonList();
        //比如获取所有年龄的总和
        //方式一
        Optional<Integer> total = personList.stream().map(Person::getAge).reduce(Integer::sum);
        System.out.println(total); //Optional[142]

        //方式二
        Optional<Integer> total1 = personList.stream().map(Person::getAge).reduce((p1, p2) -> p1 + p2);
        System.out.println(total1);// Optional[142]
    }

    //收集
    @Test
    public void test3() {
        //collect(Collector c) -将流转换为其他形式
        List<Person> list = getPersonList();
        //获取年龄大于20的person的list
        List<Person> persons = list.stream().filter(p -> p.getAge() > 20).collect(Collectors.toList());
        System.out.println(persons.toString());//[Person{id=1004, name='dahei', age=22}, Person{id=1006, name='lilan', age=23}, Person{id=1007, name='lisiu', age=25}]
        persons.forEach(System.out::println);
        System.out.println();

        Set<Person> set = list.stream().filter(p -> p.getAge() > 20).collect(Collectors.toSet());
        set.forEach(System.out::println);
    }

}

5.Optinal的使用
1)用到的实体类

package com.yl.pdfdemo.day08.p8;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description
 * @Version 1.0
 */

public class Boy {
    private Girl girl;

    public Boy() {
    }

    public Boy(Girl girl) {
        this.girl = girl;
    }

    public Girl getGirl() {
        return girl;
    }

    public void setGirl(Girl girl) {
        this.girl = girl;
    }

    @Override
    public String toString() {
        return "Boy{" +
                "girl=" + girl +
                '}';
    }
}

package com.yl.pdfdemo.day08.p8;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description
 * @Version 1.0
 */

public class Girl {
    private String name;

    public Girl() {
    }

    public Girl(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                '}';
    }
}

2)测试

package com.yl.pdfdemo.day08.p8;

import org.junit.Test;

import java.util.Optional;

/**
 * @Author wfj
 * @Date 2021/7/14
 * @Description Optional类:为了在程序中避免空指针的出现
 * @Version 1.0
 */

public class OptionalTest {

    /**
     * 1.创建Optional类实例的方法
     *     Optional.of(T t) 创建一个Optional的实例,t不能为空
     *     Optional.empty() 创建一个空的Optional实例
     *     Optional.ofNullable(T t) t可以为null
     *
     *  2.判断Optional容器内是否包含对象
     *      boolean isPresent() :判断是否包含对象
     *      void ifPresent(Consumer<? super T> consumer) :如果有值,就执行Consumer接口实现的代码,并且该值会作为参数传递给它
     *
     *  3.获取Optional容器内的对象
     *      T get():如果调用对象包含值,则返回值,否则抛异常
     *      T orElse(T other) :如果有值则将其返回,否则,返回other
     *      T orElseGet(Supplier<? extends T> other) :如果有值将其返回,否则返回由Supplier接口实现提供的对象
     *      T orElseThrow(Supplier<? extends X> exceptionSupplier) :如果有值将其返回,否则抛出由Supplier接口实现提供的异常
     */
    @Test
    public void test1() {
        Girl g1 = new Girl();
        Optional<Girl> opg1 = Optional.of(g1);
        System.out.println(opg1);//Optional[Girl{name='null'}]
        Optional<Object> empty = Optional.empty();
        System.out.println(empty); //Optional.empty
        Girl g2 = new Girl();
        g2 = null;
        Optional<Girl> opg2 = Optional.ofNullable(g2);
        System.out.println(opg2);//Optional.empty
        //orElse(T t):如果当前Optional内部的t是非空的,返回t,否则返回orElse()方法中的t
        Girl girl = opg2.orElse(new Girl("xiaolan"));
        System.out.println(girl);
    }

    @Test
    public void test2() {
        Boy boy = new Boy();
        //会报空,因为没有Girl
      //  String girlName = getGirlName(boy);

        String girlName1 = getGirlName1(boy);
        System.out.println(girlName1);//小兰
    }

    public String getGirlName(Boy boy) {
        return boy.getGirl().getName();
    }

    //使用Optional类改造
    public String getGirlName1(Boy boy) {
        Optional<Boy> optionalBoy = Optional.ofNullable(boy);
        Boy boy1 = optionalBoy.orElse(new Boy(new Girl("小芳")));
        Girl girl = boy1.getGirl();
        Optional<Girl> girlOptional = Optional.ofNullable(girl);
        Girl girl1 = girlOptional.orElse(new Girl("小兰"));
        return girl1.getName();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值