栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java学习笔记8 -- java新特性

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java学习笔记8 -- java新特性

目录
  • 1 lambda表达式 [完整笔记](https://blog.csdn.net/PorkBird/article/details/113727704)
    • 1.1 定义
    • 1.2 细节
    • 1.3 格式
      • 1.3.1 无参无返回值
      • 1.3.2 有参无返回值
      • 1.3.3 多个参数、多条语句且有返回值
  • 2 函数式接口
    • 2.1 定义
    • 2.2 自定义函数式接口
    • 2.3 与lambda表达式的关系
    • 2.4 作为参数传递的lambda表达式
    • 2.5 Java 内置四大核心函数式接口
    • 2.6 使用场景
  • 3 方法引用、构造器引用、数组引用
  • 4 Stream API
    • 4.1 概述
    • 4.2 Stream与Collection的区别
    • 4.3 细节
    • 4.4 三个步骤
    • 4.5 Stream的实例化
      • 4.5.1 通过集合
      • 4.5.2 通过数组
      • 4.5.3 通过Stream的静态方法of
      • 4.5.4 创建无限流
    • 4.6 Stream的中间操作
      • 4.6.1 切片
      • 4.6.2 映射
      • 4.6.3 排序
    • 4.7 Stream的终止操作
      • 4.7.1 细节
      • 4.7.2 匹配
      • 4.7.3 查找
      • 4.7.4 规约
      • 4.7.5 收集
  • 5 Optional类
    • 5.1 定义
    • 5.2 作用
    • 5.3 实例化Optional对象的三种方式
    • 5.4 获取Optional容器的对象
    • 5.5 判断Optional容器中是否包含对象
    • 5.6 实例

java8新特性

1 lambda表达式 完整笔记 1.1 定义

Lambda 是一个匿名函数,本质上是函数式接口的实例。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

1.2 细节
  1. 如果方法体中只有1条语句,可以省略{},如果是return语句,必须同时省略return和{}
  2. 如果参数列表只有一个参数,可以省略();
  3. 类型推断:参数列表中可以只写变量名,省略数据类型;
  4. 使用前提:当需要对一个函数式接口实例化时,才可以使用lambda表达式
1.3 格式

-> : lambda操作符或者箭头操作符;
操作符左边:Lambda形参列表(接口中抽象方法的形参列表);
操作符右边:Lambda体(重写的抽象方法的方法体)

1.3.1 无参无返回值
  Runnable r = new Runnable() {
      @Override
      public void run() {
          System.out.println(111);
      }
  };
  r.run();

如果方法体中只有1条语句,可以不用带{};

 Runnable r1 = () -> {
            System.out.println(2222);
            System.out.println("1111");
        };
        r1.run();
1.3.2 有参无返回值
        Consumer c = new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        c.accept("123");

如果只有一个参数,可以不写();

        Consumer c1 = s -> System.out.println(s);
        c1.accept("456");
1.3.3 多个参数、多条语句且有返回值
        Comparator c = new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return Integer.compare(o1, o2);
            }
        };
        int compare = c.compare(10, 8);
        System.out.println(compare);
        Comparator c1 = (o1, o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return Integer.compare(o1, o2);
        };
        System.out.println(c1.compare(8, 9));
        Comparator c1 = (o1, o2) -> {
            return Integer.compare(o1, o2);
        };

大括号与return必须同时去除

Comparator c1 = (o1, o2) ->  Integer.compare(o1, o2);
2 函数式接口 2.1 定义

只包含一个抽象方法的接口称为函数式接口。

2.2 自定义函数式接口

@FunctionalInterface是函数式接口的注解,编译时可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。

@FunctionalInterface
public interface MyFunctional {
    void method();
}
2.3 与lambda表达式的关系
  1. 在Java8中,Lambda表达式就是一个函数式接口的实例。这就是Lambda表达式和函数式接口的关系。也就是说,只要一个对象是函数式接口的实例,那么该对象就可以用Lambda表达式来表示。
  2. 所以以前用匿名实现类表示的现在都可以用Lambda表达式来写。
2.4 作为参数传递的lambda表达式
    @Test
    public void test3() {
        method1(new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        }, "abc");
        System.out.println("----------------------------");
        method1(s -> System.out.println(s), "cde");
    }

    public void method1(Consumer c, String str) {
        c.accept(str);
    }
2.5 Java 内置四大核心函数式接口

2.6 使用场景

在开发中,当我们需要定义一个函数式接口时,首先可以看一下jdk中提供的函数式接口是否满足我们的需求,如果满足,直接调用即可。

3 方法引用、构造器引用、数组引用


如果不熟悉方法引用,可以使用lambda表达式。

4 Stream API 4.1 概述
  1. Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。
4.2 Stream与Collection的区别

Stream是有关数据计算的,是面向cpu的,通过cpu实现计算;
Collection是静态的内存数据结构,面向内存,用内存存储数据。

4.3 细节
  1. Stream类似于迭代器,本身不存储元素;
  2. Stream不会改变源对象,它们会返回一个带有结果的新Stream;
  3. Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行;
4.4 三个步骤
  1. 实例化Stream对象;
  2. 中间操作(过滤、映射…);
  3. 终止操作,一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用。
4.5 Stream的实例化 4.5.1 通过集合

Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:
default Stream stream() : 返回一个顺序流
default Stream parallelStream() : 返回一个并行流

   List list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    Stream stream = list.stream();
    Stream integerStream = list.parallelStream();
4.5.2 通过数组

Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:
static Stream stream(T[] array): 返回一个流

   int[] arr = {1, 2, 3, 4, 5};
   IntStream stream = Arrays.stream(arr);

   String[] strs = {"a", "b"};
   Stream stream1 = Arrays.stream(strs);
4.5.3 通过Stream的静态方法of

public static Stream of(T… values) : 返回一个流

Stream integerStream = Stream.of(1, 2, 3, 4, 5);
4.5.4 创建无限流

可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。
迭代:public static Stream iterate(final T seed, final UnaryOperator f)
生成:public static Stream generate(Supplier s)

4.6 Stream的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

4.6.1 切片

//        filter:筛选
        List employees = EmployeeData.getEmployees();
        Stream stream = employees.stream();
        stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println);
        System.out.println();
//        limit:截取前n个元素
        employees.stream().limit(4).forEach(System.out::println);
        System.out.println();
//        skip:跳过前n个元素
        employees.stream().skip(3).forEach(System.out::println);
        System.out.println();
//       distinct:根据流所生成的hashcode和equal去除重复元素
        employees.stream().distinct().forEach(System.out::println);
4.6.2 映射

使用映射可以获取流中对象的某个属性,然后使用规约来计算所以对象属性的和。

  1. map
输出所有员工姓名长度大于3的姓名:先映射获取所有员工的姓名,然后再过滤名字长度小于等于3的
EmployeeData.getEmployees().stream().map(str -> str.getName()).filter(str -> str.length() > 3).forEach(System.out::println);
  1. flatMap

flatMap(Function f) 相当于List中的addAll方法,addAll是将另一个集合拆分后添加到当前集合中。如果flatMap中的参数是一个Stream,那么会将这个流拆分后添加到当前流中。

        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
//        list.add(Arrays.asList(4, 5, 6));[1, 2, 3, [4, 5, 6]]
        list.addAll(Arrays.asList(4, 5, 6));[1, 2, 3, 4, 5, 6]
        System.out.println(list);
    public void test10(){
        List list = Arrays.asList("aa","bb","cc");

//        使用map:返回值是Stream中嵌套Stream,需要使用双层嵌套去遍历,相当于[[a,a],[b,b],[c,c]]
        Stream> streamStream = list.stream().map(this::getCharacter);
        streamStream.forEach(s -> s.forEach(System.out::println));
//      使用flatMap:返回值是Stream,直接遍历即可,相当于[a,a,b,b,c,c]
        Stream characterStream = list.stream().flatMap(this::getCharacter);
        list.stream().flatMap(this::getCharacter).forEach(System.out::print);
    }
    public Stream getCharacter(String str){
        Character[] c = new Character[str.length()];
        for (int i = 0; i < str.length(); i++) {
            c[i] = str.charAt(i);
        }
        return Arrays.stream(c);
    }
4.6.3 排序

  1. 自然排序要求生成Stream流的元素必须实现Comparable接口;
  2. 定制排序
定制排序,需要实现Compactor接口,此处使用方法引用
    public void test11() {
        List list = Arrays.asList(5, 3, 1, 7, 9);
        下面两种输出方式相同,只是lambda表达式可以输出更多内容
        list.stream().sorted((Integer::compare)).forEach(o -> System.out.println(o + " "));1 3 5 7 9 
        list.stream().sorted((Integer::compare)).forEach(System.out::print); 13579
    }
对EmployeeData中的元素进行排序,先按年龄进行排序,年龄相同按薪资排序
        Stream stream = EmployeeData.getEmployees().stream();
        stream.sorted((o1, o2) -> {
            int res = Integer.compare(o1.getAge(), o2.getAge());
            if (res != 0) {
                return res;
            } else {
                return Double.compare(o1.getSalary(), o2.getSalary());
            }
        }).forEach(System.out::println);
4.7 Stream的终止操作 4.7.1 细节
  1. 终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。
  2. 流进行了终止操作后,不能再次使用。
4.7.2 匹配

练习:检查所有员工的年龄是否都大于18
Stream stream = EmployeeData.getEmployees().stream();
boolean b = stream.allMatch(employee -> employee.getAge() > 18);
4.7.3 查找

4.7.4 规约

    public void test12() {
//        规约操作 reduce
//        练习1:计算自然数1-10的和
        List list = new ArrayList();
        for (int i = 1; i < 11; i++) {
            list.add(i);
        }
//        第一个参数是初始值,第二个参数是运算规则
        Integer reduce = list.stream().reduce(0, Integer::sum);
        System.out.println(reduce);
    }
//        计算公司中所有员工的工资总和
        Stream stream = EmployeeData.getEmployees().stream();
//        先使用map获取所有员工的工资,然后使用reduce将其累加
        Optional reduce = stream.map(employee -> employee.getSalary()).reduce(Double::sum);
        System.out.println(reduce);
4.7.5 收集


Collector 接口中方法的实现决定了如何对流执行收集的操作,也就是将stream流转换成其他数据结构(如收集到 List、Set、Map)。
另外, Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

//        练习:查找工资大于6000的员工,结果返回一个List或Set
        Stream stream = EmployeeData.getEmployees().stream();
        List collect = stream.filter(e -> e.getSalary() > 6000).collect(Collectors.toList());
        Set set = stream.filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());
5 Optional类 5.1 定义

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

5.2 作用

为了避免空指针异常,使用Optional,不需要再显式判断对象是否为null。

5.3 实例化Optional对象的三种方式
  1. Optional.of(T t):t不能为null;
  2. Optional.empty():创建一个空的Optional实例;
  3. Optional.ofNullable(T t):t可以为null;
5.4 获取Optional容器的对象
  1. T get(): 如果调用对象不为空,返回该值,否则抛异常。
  2. T orElse(T other) :如果有值则将其返回,否则返回指定的other对象。(一般使用此方法来避免空指针异常)
  3. T orElseGet(Supplier other) :如果有值则将其返回,否则返回由Supplier接口实现提供的对象。
  4. TorElseThrow(Supplier exceptionSupplier) :如果有值则将其返回,否则抛出由Supplier接口实现提供的异常。
5.5 判断Optional容器中是否包含对象
  1. boolean isPresent() : 判断是否包含对象。
  2. void ifPresent(Consumer consumer) :如果有值,就执行Consumer接口的实现代码,并且该值会作为参数传给它。
5.6 实例
        Optional o = Optional.of("123");
        System.out.println(o);
        Optional empty = Optional.empty();
        System.out.println(empty);
        
        o1中的对象为空,所以返回指定值“123”
        Optional o1 = Optional.ofNullable(null);
        Object o2 = o1.orElse("123");
        System.out.println(o2); // 123


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号