javaSE-jdk1.8新特性

一.Lambda表达式

1.概述

Lambda表达式是一种没有名字的函数,也可称为闭包,是Java 8 发布的最重要新特性。

本质上是一段匿名内部类,也可以是一段可以传递的代码。

还有叫箭头函数的…

2.闭包的概念

闭包就是能够读取其他函数内部变量的函数,比如在java中,方法内部的局部变量只能在方法内部使用,所以闭包可以理解为定义在一个函数内部的函数

闭包的本质就是将函数内部和函数外部链接起来的桥梁

3.特点

允许把函数作为一个方法的参数(函数作为参数传递进方法中)。

使用 Lambda 表达式可以使代码变的更加简洁紧凑。

4.应用场景

列表迭代

Map映射

Reduce聚合

代替一个不想命名的函数或是类,该函数或类往往并不复杂。

想尽量缩短代码量的各个场景均可以

5.具体的语法

1、(parameters) -> expression

2、(parameters) ->{ statements; }

6.语法特点

可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。

可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

可选的大括号:如果主体包含了一个语句,就不需要使用大括号。

可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值

如果只有一条语句,并且是返回值语句,就可以不写return 不写 {}

如果写上{} 就必须写return 和 ;

如果有 多条语句,必须写{} return 和 ; 也必须写

7.简单的例子

// 1. 不需要参数,返回值为 5  
() -> 5  

// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2*x  

// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  

// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  

// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)
//1.简单使用lambda表达式进行遍历
String[] array = {"abc","cab","bca"};
List<String> list = Arrays.asList(array);
list.forEach(x->System.out.println(x));
        
//2.给集合排序
list.sort((x,y)->x.compareTo(y));
list.forEach(x->System.out.println(x));

8.函数式接口

8.1概述

英文称为Functional Interface

其本质是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

核心目标是为了给Lambda表达式的使用提供更好的支持,进一步达到函数式编程的目标,可通过运用函数式编程极大地提高编程效率。

其可以被隐式转换为 lambda 表达式。

8.2特点

函数式接口是仅制定一个抽象方法的接口

可以包含一个或多个静态或默认方法

专用注解即@FunctionalInterface 检查它是否是一个函数式接口,也可不添加该注解

如果有两个或以上 抽象方法,就不能当成函数式接口去使用,也不能添加@FunctionalInterface这个注解

如果只有一个抽象方法,那么@FunctionalInterface注解 加不加 都可以当做函数式接口去使用

8.3代码实现

pa

ckage homework;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
 * 
 * @author Antg
 * @date 2021年7月5日
 * @Description
 * lambda表达式的练习
 */
public class Hw01 {
    public static void main(String[] args) {
        
        //3.函数式接口(无参)
        //3.1第一种调用方式
        call(()->{System.out.println("这个是一个回调函数");});
        
        //3.2第二种调用方式
        FuncInterfaceNoParam func = ()->{System.out.println("这个是一个回调函数2");};
        func.callback();
        
        //4.函数式接口(有参)
        callWithParam((String name)->{System.out.println("有参的函数式接口,参数:"+name);},"张三");

    }
    
    //定义一个静态方法,接收函数式接口(无参)
    public static void call(FuncInterfaceNoParam func){
        func.callback();
    }
    //定义一个静态方法,接收函数式接口(有参)
    public static void callWithParam(FuncInterfaceHavingParam func,String name){
        func.callback(name);
    }
}
package homework;

public interface FuncInterfaceHavingParam {
    public void callback(String name);
}

package homework;
//无参函数式接口
/*
 * 函数式接口只能有一个抽象方法,但是可以有多个非抽象方法
 * */
@FunctionalInterface
public interface FuncInterfaceNoParam {
    //这是一个回调函数
    public void callback();
}

9.JDK自带常用的函数式接口

9.1Supplier<T>接口

Supplier<T>接口 代表结果供应商,所以有返回值,可以获取数据

有一个get方法,用于获取数据

9.2 Consumer<T>接口

Consumer<T>接口 消费者接口所以不需要返回值

有一个accept(T)方法,用于执行消费操作,可以对给定的参数T 做任意操作

9.3Function<T,R>接口

Function<T,R>接口 表示接收一个参数并产生结果的函数

顾名思义,是函数操作的

有一个R apply(T)方法,Function中没有具体的操作,具体的操作需要我们去为它指定,因此apply具体返回的结果取决于传入的lambda表达式

9.4Predicate<T>接口

Predicate<T>接口 断言接口

就是做一些判断,返回值为boolean

有一个boolean test(T)方法,用于校验传入数据是否符合判断条件,返回boolean类型

9.5例子

package homework;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
 * 
 * @author Antg
 * @date 2021年7月5日
 * @Description
 * lambda表达式的练习
 */
public class Hw01 {
    public static void main(String[] args) {
        
        
        //5.jdk自带的函数式接口
        //5.1  Supplier<T>
        System.out.println(call(()->"Supplier接口可以用来获取值"));
        //5.2  Consumer<T>
        call(()->{System.out.println("Consumer接口可以用来处理传入的数据");});
        //5.3  Function<T,R>
        System.out.println("Function接口的函数,将String类型转换成int类型:"+call((String param)->{return Integer.valueOf(param);},"123"));
        //5.4  Predicate<T> 断言接口
        call((p)->{return p==1;},1);
        
            
        
    }

    //Supplier接口
    public static String call(Supplier<String> func){
        return func.get();
    }
    //Comsumer接口
    public static void call(Consumer<String> func,String param){
        func.accept(param);
    }
    //Function接口
    public static Integer call(Function<String, Integer> func,String param){
        return func.apply(param);
    }
    //Predicate接口
    public static void call(Predicate<Integer> func,Integer param){
        if(func.test(param)){
            System.out.println("条件符合要执行的操作");
        }else{
            System.out.println("条件不符合要执行的操作");
        }
    }    
}

10.方法引用和构造器使用

10.1概述

Lambda表达式的另外一种表现形式,提高方法复用率和灵活性。

10.2 特点

更简单、代码量更少、复用性、扩展性更高。

10.3代码实现

package homework;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
 * 
 * @author Antg
 * @date 2021年7月5日
 * @Description
 * lambda表达式的练习
 */
public class Hw01 {
    public static void main(String[] args) {
        
        //6.方法引用
        //常规lambda写法
        Supplier<String> sup = () -> new Integer(123456).toString();
        System.out.println("普通lambda写法"+sup.get());
        //使用方法引用
        //对象的引用 :: 实例方法名
        Supplier<String> sup2 = new Integer(123456)::toString;
        System.out.println("方法引用1"+sup2);
        //类名 :: 静态方法名
        BiFunction<Integer, Integer, Integer> bif = Integer::max;
        System.out.println("方法引用2"+bif.apply(10, 11));
        //类名 :: 实例方法名
        BiPredicate<String, String> bp = String::equals;
        System.out.println("方法引用3"+bp.test("aaa", "bbb"));
        
        
        //7.构造器调用
        //普通lambda写法
        Supplier<Object> objSup1 = ()->new Object();
        System.out.println(objSup1.get());
        //使用方法引用
        //无参构造
        Supplier<Object> objSup2 = Object::new;
        System.out.println(objSup2.get());
        //有参构造
        Function<String,Integer> objSup3 = Integer::new;
        System.out.println(objSup3.apply("123"));
        
        //8.数组的调用
        //普通lambda写法
        Function<Integer, Integer[]> f1 = (n)->new Integer[n];
        Integer[] integerArray = f1.apply(5);
        integerArray[0] = 100;
        System.out.println(integerArray[0]);
        
        //数组的新写法
        Function<Integer, Integer[]> f2 = Integer[]::new;
        Integer[] integerArray2 = f1.apply(5);
        integerArray2[0] = 100;
        System.out.println(integerArray2[0]);

        
    }
    
    
}

二.Stream API

1.概述

数据渠道、管道,用于操作数据源(集合、数组等)所生成的元素序列。

集合讲的是数据,流讲的是计算

即一组用来处理数组,集合的API。

2.特点

Stream 不是数据结构,没有内部存储,自己不会存储元素。

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

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

不支持索引访问。

延迟计算

支持并行

很容易生成数据或集合

支持过滤,查找,转换,汇总,聚合等操作。

3.应用场景

流式计算处理,需要延迟计算、更方便的并行计算

更灵活、简洁的集合处理方式场景

4.运行机制

Stream分为源source,中间操作,终止操作。

流的源可以是一个数组,集合,生成器方法,I/O通道等等。

一个流可以有零个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作。

中间操作也称为转换算子-transformation

Stream只有遇到终止操作,它的数据源会开始执行遍历操作。

终止操作也称为动作算子-action

因为动作算子的返回值不再是 stream,所以这个计算就终止了

只有碰到动作算子的时候,才会真正的计算

5.生成strea流的五种方式

//1.通过数组的Stream.of()方法
String[] strArray = {"one","two","three","four"};
Stream<String> stream1 = Stream.of(strArray);

//2.通过集合
List<String> list1 = Arrays.asList(strArray);
Stream<String> stream2 = list1.stream();

//3.通过Stream.generate方法来创建
Stream<Integer> stream3 = Stream.generate(()->1);
stream3.limit(10).forEach(x->System.out.println(x));

//4.通过iterate
Stream<Integer> stream4 = Stream.iterate(1, x->x+2);
stream4.limit(5).forEach(x->System.out.println(x));

//5.已有类的stream源生成API
String str2 = "123456";
IntStream chars = str2.chars();
chars.forEach(x->System.out.println(x));

6.常用的转换算子

常用转换算子 filter,distinct,map,limit,skip,flatMap等

filter : 对元素进行过滤筛选,不符合的就不要了

distinct : 去掉重复的元素

skip : 跳过多少元素

limit : 取一个集合的前几条数据

map :
可以理解是在遍历集合的过程中,对元素进行操作,比如判断集合元素是否是a 返回boolean
因为 map的返回值,就是新集合中的元素,所以也可以在遍历的时候对集合的数据进行更改,比如都加 –

flatMap : 解决一个字符串数组 返回单一的字符串使用flatMap
本来集合中有两个数组,可以通过flatMap 把数组中的每一个元素都放到集合中,然后把数组去掉

注意只用此算子是不会真正进行计算的,只有后边调用动作算子才会真正计算。

7.常用的动作算子

循环 forEach
计算 min、max、count、average

匹配 anyMatch、allMatch、noneMatch、findFirst、findAny

汇聚 reduce

收集器 collect

三.接口新特性

1.概述

1.8之前接口中只能定义public static final的变量和public abstract修饰的抽象方法。

1.8及以后版本,不仅兼容1.8以前的,并新增了默认方法定义和静态方法定义的功能。

即default方法和static方法。

让接口更灵活、更多变,更能够适应现实开发需要。

2.特点

默认方法

可以被重写,也可以不重写。如果重写的话,就按实现类的方法来执行。

调用的时候必须是实例化对象调用。

静态方法

跟之前的普通类的静态方法大体相同

唯一不同的是不能通过接口的实现类的对象来调用,必须是类.静态方法的方式。

3.代码实现

package homework;
/**
 * 
 * @author Antg
 * @date 2021年7月5日
 * @Description
 * 接口中的默认方法和静态方法
 */
public class Hw03 {
    public static void main(String[] args) {
        TestImpl testImpl = new TestImpl();
        //接口的默认方法只能用实现类的实例来调用
        testImpl.m1();
        //接口的静态方法可以用接口名
        TestInterface.m2();
    }
    
    public static interface TestInterface{
        //默认方法
        public default void m1(){
            System.out.println("这里是接口的默认方法");
        }
        public static void m2(){
            System.out.println("这里是静态方法");
        }
    }
    //实现上述接口
    public static class TestImpl implements TestInterface{
        
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mizui_i

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

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

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

打赏作者

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

抵扣说明:

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

余额充值