Java8新特性——————Stream API和Optional类

Stream API

1,Stream API的理解:

①,Stream关注的是对数据的运算,与CPU打交道。集合关注的是数据的储存,与内存打交道

②,java8提供了一套api,使用这套api可以对内存中的数据进行过滤,排序,映射,归约等操作。类似于sql对数据库中表的相关操作。

2,注意点

①,Stream 自己不会存储元素

②,Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream

③,Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

3,Stream执行流程

①,Stream 的实例化

②,一系列的中间操作(过滤,映射,…)

③,终止操作

4,说明:

一个中间操作链,对数据源的数据进行处理

一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

5,Stream的中间操作:

①,筛选与切片
在这里插入图片描述
代码如下:

@Test
public void test4(){
    List<Employee> list = EmployeeData.getEmployees();
    Stream<Employee> stream = list.stream();
    //filter
    stream.filter(e ->e.getSalary() > 7000).forEach(System.out::println);
    //limit
    list.stream.limit(3).forEach(System.out::println);
    //limit
    list.stream.skip(3).forEach(System.out::println);
    //distinct
    list.stream.distinct().forEach(System.out::println);
}

②,映射
在这里插入图片描述
代码如下:

  @Test
    public void test4(){
        List<String> list = Arrays.asList("AA","BB","cc","dd");
        list.stream().map(str -> str.toLowerCase()).forEach(System.out::println);
        //获取员工姓名长度大于3的员工姓名
        List<Employee> employees = EmployeeData.getEmployees();
        //map和filter
        Stream<String> namesStream = employees.stream().map(Employee::getName);
        namesStream.filter(name -> name.length() > 3).forEach(System.out::println);

        //map
        Stream<Stream<Character>> streamStream = list.stream().map(ProxyTest::fromStringToStream);
        streamStream.forEach(s -> s.forEach(System.out::println));
        //flatMap
        Stream<Character> characterStream = list.stream().flatMap(ProxyTest::fromStringToStream);
        characterStream.forEach(System.out::println);
        
    }

    public static Stream<Character> fromStringToStream(String str){
        ArrayList<Character> list = new ArrayList<>();
        for (Character character : str.toCharArray()){
            list.add(character);
        }
        return  list.stream();
    }

③,排序
在这里插入图片描述
代码如下:

@Test
public void test7() {
    //sorted()-自然排序
    List<Integer> list = Arrays.asList(12, 43, 34, 87, -98, 7);
    list.stream().sorted().forEach(System.out::println);
    //sorted(Comployee com)-定制排序
    List<Employee> employees = EmployeeData.getEmployees();
    employees.stream().sorted((e1, e2) -> {
        int ageValue = Integer.compare(e1.getAge(), e2.getAge());
        if (ageValue != 0) {
            return ageValue;
        } else {
            return -Double.compare(e1.getSalary(), e2.getSalary());
        }
    }).forEach(System.out::println);
    
}

6,Stream的终止操作:

①,匹配与查找
在这里插入图片描述在这里插入图片描述
代码如下:

@Test
public void test7() {
    List<Employee> employees = EmployeeData.getEmployees();
    //allMatch(predicate p)-检查是否匹配所有元素
    boolean allMatch = employees.stream().allMatch(e -> e.getAge() >18);
    //anyMatch(Predicate P)-检查是否至少匹配一个元素。
    boolean anyMatch = employees.stream().anyMatch(e ->e.getSalary() > 10000);
    //noneMatch(Predicate p)一 检查是否没有匹配的元素。
    boolean noneMatch = employees.stream().noneMatch(e -> e.getName().tartsWith("周"));
    ///findFirst- 返回第一 个元囊
    Optional<Employee> employee = employees.stream().findFirst();
    //findAny- -返回当前流中的任意元素
    optiona1<Employee> employee1 = employees.paralle1Stream().findAny();
    // count- 返回流 中元素的总个数
    long count = employees. stream().filter(e -> e.getSalary() > 5000).count();
    //max(Comparator c)一返回流中最大值
    Stream<Double> salaryStream = employees.stream().map(e -> e.getSalary());
    Optional<Double> maxsalary = salaryStream.max(Double :: compare);
    //min(Comparator c)-返回流 中最小值
    Optional<Employee> minsalary = employees.stream().min((e1,e2) -> Double.compare(e1.getSalary(), e2.getsalary()));
    //forEach(Consumer c)一内部迭代
    employees.stream().forEach(System.out :: print1n);
}

②,归约
在这里插入图片描述
代码如下:

@Test
public void test7() {
    //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);//sun-->55
    //reduce(BinaryOperator)一可以将流中元素反复结合起来,得到一个值。返回optional<T>
    //计算公司所有员工工资的总和
    List<Employee> employees = EmployeeData.getEmployees();
    Stream<Double> salaryStream = emp1oyees.stream().map(Emp1oyee :: getSalary);
    Optional <Double> sumMoney = salaryStream. reduce(Double::sum);
}

③,收集
在这里插入图片描述
代码如下:

@Test
public void test7() {
    List<Employee> employees = Emp1oyeeData.getEmployees();
    List<Employee> employeelist = employees.stream().filter(e -> e.getSalary() > 8000).collect(Collectors.toList());
}

Optional类

1,Optional类的介绍

      Optional 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。

2,Optional 类对象的方法

  • Optional.of(T t) : 创建一个 Optional 实例,t必须非空;
  • Optional.empty() : 创建一个空的 Optional 实例
  • Optional.ofNullable(T t) :t可以为null

3,判断Optional 容器中是否包含对象:

  • boolean isPresent() : 判断是否包含对象
  • void ifPresent(Consumer<? super T> consumer) :如果有值,就执行Consumer
    接口的实现代码,并且该值会作为参数传给它。
  • 获取Optional 容器的对象:
  • T get(): 如果调用对象包含值,返回该值,否则抛异常
  • T orElse(T other) :如果有值则将其返回,否则返回指定的other对象。
  • T orElseGet(Supplier<? extends T> other) : :如果有值则将其返回,否则返回由

4,Supplier接口实现提供的对象

  • T orElseThrow(Supplier<? extends X> exceptionSupplier) : :如果有值则将其返
    回,否则抛出由Supplier接口实现提供的异常。

5,Optional类的使用

@Test
public void test7() {
    Girl girl = new Gir1();
    girl = nu11;
    //of(T t):保证t是非空的
    optional<Girl> optiona1Girl = Optional.of(gir1);
    //ofNullable(T t): t可以为null
    optional<Girl> optiona1Girl1 = Optional.ofNullable(gir1);
}

@Test
public void test2() {
    Boy b = new Boy("张三");
    Optional<Girl> opt = Optional.ofNullable(b.getGrilFriend());
    // 如果有女朋友就返回他的女朋友,否则只能欣赏“嫦娥”了
    Girl girl = opt.orElse(new Girl("嫦娥"));
    System.out.println("他的女朋友是:" + girl.getName());
发布了67 篇原创文章 · 获赞 19 · 访问量 9867

猜你喜欢

转载自blog.csdn.net/qq_41530004/article/details/104423252