java8特性

java8特性

一,Lambda表达式

###1,Lambda表达式介绍

Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以 传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了

提升。

2,Lambda表达式使用

1,举例说明:(o1,o2)-> Integer.compare(o1,o2)

2,格式:

->:Lambda操作符号或者箭头操作符

->:左边:Lambda形参列表(接口中抽象方法中的形成列表)

->:右边:Lambda方法体(其实就是重写的抽象方法的方法体)

1,语法格式一:无参,无返回值

@Test
    public void test002(){
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("李狗蛋!");
            }
        };
        r1.run();
        System.out.println("Lambda表达式使用如下");

        Runnable r2 = ()-> System.out.println("李狗蛋!");
        r2.run();
    }

2,语法格式二:Lambda需要一个参数,但是没有返回值。

@Test
    public void test001(){
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("李狗!!!!!!!");

        System.out.println("Lambda表达式使用如下");
        Consumer<String> consumer1 =(String str) -> System.out.println(str);
        consumer1.accept("李狗!!!!!!!");
    }

3,语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”

@Test
    public void test001(){
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("李狗!!!!!!!");

        System.out.println("Lambda表达式使用如下");
        //其中下面写法类型可以省略,类型推断
        Consumer<String> consumer2 =(str) -> System.out.println(str);
        consumer2.accept("李狗!!!!!!!");
    }

4,语法格式四:Lambda若只需要一个参数时,参数的小括号可以省略

@Test
    public void test001(){
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("李狗!!!!!!!");

        System.out.println("Lambda表达式使用如下");
        Consumer<String> consumer1 =str -> System.out.println(str);
        consumer1.accept("李狗!!!!!!!");
    }

5,语法格式五:Lambda需要两个或以上的参数,多条执行语句,并且可以有返回值

@Test
    public void test003(){
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(comparator.compare(12,13));

        System.out.println("Lambda表达式使用如下");
        Comparator<Integer> comparator1 = (o1,o2)-> {
            System.out.println(o1);
            System.out.println(o2);
            return o1.compareTo(o2);
        };
        System.out.println(comparator1.compare(12,13));
    }

6,语法格式六:当 Lambda 体只有一条语句时,return与大括号若有,都可以省略

@Test
    public void test2(){
        Comparator<Integer> comparator1 = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        int compare = comparator1.compare(12, 11);
        System.out.println(compare);

        Comparator<Integer> comparator2 = (o1,o2)-> Integer.compare(12,13);
    }

二,函数式(Functional)接口

1,什么是函数式(Functional)接口

  1. 只包含一个抽象方法的接口,称为函数式接口
  2. 可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检 查它是否是一个函数式接口。
  3. Lambda表达式就是一个函数式接口的实例。
  4. 只要一个对象是函数式接口 的实例,那么该对象就可以用Lambda表达式来表示。

三,方法引用和构造器引用

1,使用方法引用的场景

  1. 当要传递给Lambda表达式的操作,已经有实现方法了,可以使用方法引用

  2. 方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口实例,所以方法引用也是函数式接口实例

  3. 使用格式:类(或者对象):: 方法名

  4. 具体分为三种情况

    • 对象::非静态方法

       @Test
          public void test11(){
              //对象::非静态方法
              Consumer<String> consumer = str -> System.out.println(str);
              consumer.accept("李狗蛋");
      
              System.out.println("方法引用");
              PrintStream out = System.out;
              Consumer<String> consumer1 = out::println;
          }
      
    • 类::静态方法

          @Test
          public void test12(){
              System.out.println("Lambda表达式");
              Comparator<Integer> com = (t1,t2) -> Integer.compare(t1,t2);
              System.out.println(com.compare(12,13));
              System.out.println("方法引用");
              Comparator<Integer> com1 = Integer::compare;
              System.out.println(com1.compare(13,12));
          }
      
    • 类::非静态方法

      /**
           * Comparator中的int compare(T t1,T t2)和String中的 int t1.compareTo(t2)
           */
          @Test
          public void test13(){
              System.out.println("Lambda表达式");
              Comparator<String> com1= (s1,s2)->s1.compareTo(s2);
              System.out.println(com1.compare("abc","bcd"));
              System.out.println("方法引用");
              Comparator<String> com2= String::compareTo;
              System.out.println(com2.compare("abcd","bcd"));
          }
      

2 ,构造器引用

  1. 构造器引用

    /**
         * 构造器引用
         */
        @Test
        public void test14(){
            //原始写法
            Supplier<String> supplier = new Supplier<String>() {
                @Override
                public String get() {
                    return "构造器引用";
                }
            };
            //Lambda表达式写法
            Supplier<String> supplier1 = () -> new String("构造器引用");
            //构造器引用写法
            Supplier<String> supplier2 =String::new;
            System.out.println(supplier2);
        }
    
  2. 数组引用

    @Test
        public void test15(){
            //原始写法
            Function<Integer, String[]> function = new Function<Integer, String[]>() {
                @Override
                public String[] apply(Integer length) {
                    return new String[length];
                }
            };
    
            //Lambda表达式写法
            Function<Integer, String[]> func = length->new String[length];
            String[] apply = func.apply(3);
            System.out.println(Arrays.toString(apply));
            //数组引用写法
            Function<Integer, String[]> func1 = String[]::new;
            String[] apply1 = func1.apply(5);
            System.out.println(Arrays.toString(apply1));
        }
    

四,强大的Stream API

1,Stream API概念相关

  1. Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这 是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程 序员的生产力,让程序员写出高效率、干净、简洁的代码。

  2. Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进 行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。 使用 Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。 也可以使用 Stream API 来并行执行操作。简言之,Stream API 提供了一种 高效且易于使用的处理数据的方式。

  3. Stream 和 Collection 集合的区别:Collection 是一种静态的内存数据 结构,而 Stream 是有关计算的。前者是主要面向内存,存储在内存中, 后者主要是面向 CPU,通过 CPU 实现计算。

2,Stream 的操作三个步骤

  • 1- 创建 Stream

    • 一个数据源(如:集合、数组),获取一个流
  • 2- 中间操作

    • 一个中间操作链,对数据源的数据进行处理
  • 3- 终止操作(终端操作)

    • 一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
  • 过程如下图:

在这里插入图片描述

3,创建 Stream方式

  1. 通过集合Java8 中的 Collection 接口被扩展,提供了两个获取流 的方法:

    • default Stream stream() : 返回一个顺序流
    • default Stream parallelStream() : 返回一个并行流
  2. 通过数组Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:

    • static Stream stream(T[] array): 返回一个流
  3. 通过Stream的of():可以调用Stream类静态方法 of(), 通过显示值创建一个 流。它可以接收任意数量的参数。

    • public static Stream of(T… values) : 返回一个流
  4. 创建无限流可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。

    • 迭代 public static Stream iterate(final T seed, final UnaryOperator f)
    • 生成 public static Stream generate(Supplier s)
     Stream.iterate(0,num->num+2).limit(20).forEach(System.out::println);
     Stream.generate(Math::random).limit(5).forEach(System.out::println);
    

4,Stream 的中间操作

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

  1. 筛选与切片

    方 法描 述
    filter(Predicate p)接收 Lambda , 从流中排除某些元素
    distinct()筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
    limit(long maxSize)截断流,使其元素不超过给定数量
    skip(long n)跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一
  2. 映 射

    方法描述
    map(Function f)接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。
    mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
    mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
    mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。
    flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

五,Optional类

  1. Optional 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表 这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不 存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
  2. 这是一个可以为null的容器对象。如果值存在 则isPresent()方法会返回true,调用get()方法会返回该对象。

创建Optional类对象的方法:

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

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

  1. boolean isPresent() : 判断是否包含对象
  2. void ifPresent(Consumer consumer) **:**如果有值,就执行Consumer 接口的实现代码,并且该值会作为参数传给它。

获取Optional容器的对象

  1. T get(): 如果调用对象包含值,返回该值,否则抛异常
  2. T orElse(T other) **:**如果有值则将其返回,否则返回指定的other对象。
  3. T orElseGet(Supplier other) **:**如果有值则将其返回,否则返回由 Supplier接口实现提供的对象。
  4. T orElseThrow(Supplier exceptionSupplier) **:**如果有值则将其返 回,否则抛出由Supplier接口实现提供的异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值