16-Java-JDK8新特性

课程笔记Day16

第一章 Lambda表达式
    第01节 基础理论
    第02节 系统函数式接口
    第03节 省略策略
    第04节 Lambda和匿名内部类
第二章 方法引用
    第01节 体验一下
    第02节 成员方法引用
    第03节 静态方法引用
    第04节  构造方法引用
第三章 Stream流
    第01节 基础理论
    第02节 常用API

课程笔记Day16

Lambda 表达式
方法引用
Stream流
JDK8的时间类

第一章 Lambda表达式

第01节 基础理论

lambda表达式的体验

发现问题

以前写 匿名内部类的时候,会觉得代码非常的繁琐。写起来比较麻烦。

体验 Lambda表达式

接口

//接口

public interface JieKou {

    //抽象方法

    public abstract void methodAbstract();

}

接口实现类

//实现类

public class ShiXian implements JieKou {

    @Override

    public void methodAbstract() {

        System.out.println("接口实现类...");

    }

}

测试类

public class Test {


    public static void main(String[] args) {

        //可以使用多态的写法

        JieKou kou = new ShiXian();

        function(kou);

        //可以使用匿名内部类的写法

        function(new JieKou() {

            @Override

            public void methodAbstract() {

                System.out.println("匿名内部类");

            }

        });

        //采用Lambda表达式对于匿名内部类进行简化。

        function(()->System.out.println("Lambda"));

    }


    //将方法的参数定义为接口

    public static void function(JieKou kou){

        kou.methodAbstract();

    }

}

lambda表达式的格式

格式:

(参数列表)->{ 方法体; }

  1. 小括号:参数列表。指的是 接口当中抽象方法的参数列表。

  2. 箭头: 就是一个指向,没有具体的含义。可以理解为:将参数传递给方法体。

  3. 大括号: 方法体。指的是 接口当中抽象方法的具体实现。

前提:

如果想要使用 Lambda 表达式,则必须有 函数式接口。

什么是函数式接口呢?

函数式接口: 有且仅有一个抽象方法的接口,就叫做函数式接口。

如何去校验是否是正确的函数式接口呢?

可以采用注解 @FunctionalInterface

第02节 系统函数式接口

Supplier

源代码

//作用:只出不进

@FunctionalInterface

public interface Supplier<T> {

    T get();

}

测试类

import java.util.function.Supplier;


//目标:学习系统提供的Supplier接口

public class Test01 {


    public static void main(String[] args) {

        //匿名内部类版本

        function(new Supplier<String>() {

            @Override

            public String get() {

                return "sleep 真香";

            }

        });

        //采用 Lambda 表达式简化

        function(()->{return "sleep 真香,尤其是上课sleep";});

    }


    //定义一个方法,该方法的参数是函数式接口

    public static void function(Supplier<String> fun){

        String s = fun.get();

        System.out.println(s);

    }

}

Consumer

源代码

//作用:只进不出

@FunctionalInterface

public interface Consumer<T> {


    void accept(T t);


    default Consumer<T> andThen(Consumer<? super T> after) {

        Objects.requireNonNull(after);

        return (T t) -> { accept(t); after.accept(t); };

    }

}

测试类

import java.util.function.Consumer;


//函数式接口 Consumer的使用

public class Test02 {


    public static void main(String[] args) {

        //调用方法, 采用的是匿名内部类的写法

        function(100, new Consumer<Integer>() {

            @Override

            public void accept(Integer integer) {

                System.out.println(integer);

            }

        });


        //如果想要写 lambda表达式应该怎么写呢?

        function(100,(Integer integer)->{ System.out.println(integer);});

    }


    //函数式接口作为方法的参数传递

    public static void function(Integer ii,Consumer<Integer> fun){

        fun.accept(ii);

    }

}

Predicatie

源代码

//作用:条件判断

@FunctionalInterface

public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {

        Objects.requireNonNull(other);

        return (t) -> test(t) && other.test(t);

    }

    default Predicate<T> negate() {

        return (t) -> !test(t);

    }

    default Predicate<T> or(Predicate<? super T> other) {

        Objects.requireNonNull(other);

        return (t) -> test(t) || other.test(t);

    }

    static <T> Predicate<T> isEqual(Object targetRef) {

        return (null == targetRef)

                ? Objects::isNull

                : object -> targetRef.equals(object);

    }

}

测试类

import java.util.function.Predicate;


//目标:学习Predicate 函数式接口的使用

public class Test03 {


    public static void main(String[] args) {

        //匿名内部类

        function("张无忌", new Predicate<String>() {

            @Override

            public boolean test(String s) {

                return s.startsWith("王");

            }

        });

        //Lambda表达式的写法

        function("隔壁老王",(String s)->{return s.startsWith("王");});

    }


    public static void function(String str,Predicate<String> fun){

        boolean flag = fun.test(str);

        System.out.println("flag = " + flag);

    }

}

Function

源代码

//作用:类型转换

@FunctionalInterface

public interface Function<T, R> {


    R apply(T t);


    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {

        Objects.requireNonNull(before);

        return (V v) -> apply(before.apply(v));

    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {

        Objects.requireNonNull(after);

        return (T t) -> after.apply(apply(t));

    }

    static <T> Function<T, T> identity() {

        return t -> t;

    }

}

测试类

import java.util.function.Function;


//目标:学习 Function 函数式接口的使用

public class Test04 {


    public static void main(String[] args) {

        //匿名内部类写法

        function("hello", new Function<String, Integer>() {

            @Override

            public Integer apply(String s) {

                return s.length();

            }

        });

        //Lambda表达式的写法

        function("world",(String s)->{return s.length();});

    }


    //写一个方法,方法的参数是函数式接口

    public static void function(String str,Function<String,Integer> fun){

        Integer num = fun.apply(str);

        System.out.println(num);

    }

}

第03节 省略策略

关于 Lambda表达式,除了标准格式外,还可以继续的简化代码。

  1. 什么时候,小括号可以省略呢?

    只有一个参数的时候,可以省略小括号不写。

  2. 什么时候,大括号可以省略呢?

    在方法体当中,只有一句话的时候,可以省略大括号,分号,return语句。

  3. 百分百可以省略的是什么?

    我们 参数列表的数据类型,可以百分百省略。

第04节 Lambda和匿名内部类

说明

  1. 区别一:引用简化方式不同。

    A. 匿名内部类,他可以作用于 接口或者是类

    B. Lambda表达式, 他只能作用于函数式接口

  2. 区别二: 底层实现不同。

    A. 匿名内部类,底层产生class文件

    B. Lambda表达式,底层没有 class 文件

第二章 方法引用

第01节 体验一下

import java.util.function.Consumer;


//目标:体验方法引用的好处

public class Test01 {


    public static void main(String[] args) {

        //采用Lambda表达式的写法

        method("hello",str-> System.out.println(str));

        //直接使用方法引用

        method("world",System.out::println);


    }


    public static void method(String str,Consumer<String> con){

        con.accept(str);

    }

}
小结:

我们发现,采用方法引用,比lambda表达式更加的简单。

条件会更加的苛刻。

你要做某件事情,刚好发现别人也要做这件事情,就顺带的使用他的事情,一起做了。

第02节 成员方法引用

普通类

//学生类

public class Student {


    //定义方法,喊出你的名字

    public void callName(String name){

        System.out.println("我叫"+name);

    }

}

测试类

import java.util.function.Consumer;


public class Test02 {


    public static void main(String[] args) {

        //原始的做法:

        method("黄雨浩",name-> System.out.println("我叫"+name));

        //直接引用方法

        method("江少东",new Student()::callName);

    }


    //定义一个方法,进行自我介绍。

    public static void method(String name,Consumer<String> con){

        con.accept(name);

    }

}


//我叫黄雨浩

//我叫江少东
小结:成员方法引用格式: 对象名称::方法名称

第03节 静态方法引用

普通类

public class Teacher {


    //定义方法,喊出你的名字

    public static void callName(String name){

        System.out.println("点名"+name);

    }

}

测试类

import java.util.function.Consumer;


public class Test03 {


    public static void main(String[] args) {

        //原始的做法:

        method("黄雨浩",name-> System.out.println("点名"+name));

        //直接引用左侧的方法

        method("江少东",Teacher::callName);


    }


    //定义一个方法,进行自我介绍。

    public static void method(String name,Consumer<String> con){

        con.accept(name);

    }

}


//点名黄雨浩

//点名江少东
小结:静态方法的引用: 类名称::方法名称

第04节 构造方法引用

普通类

public class Student{


}

测试类

import java.util.function.Supplier;


//目标:学习构造方法引用

public class Test04 {


    public static void main(String[] args) {

        //将对象,进行打印输出

        Student stu1 = makeObject(() -> new Student());

        System.out.println("stu1 = " + stu1);

        //采用方法引用

        Student stu2 = makeObject(Student::new);

        System.out.println("stu2 = " + stu2);

    }


    //泛型方法。返回一个你需要的对象

    public static <T> T makeObject(Supplier<T> sup){

        T t = sup.get();

        return t;

    }

}
小结:构造方法引用格式:  类名称::new

第三章 Stream流

第01节 基础理论

我们以前针对于集合或者数组的操作是非常频繁的。

例如:

第一步做集合 筛选的操作(根据条件1筛选)

第二步做集合 筛选的操作(根据条件2筛选)

第三步做集合 合并的操作(将两个集合数据进行合并)

第四步做集合 去重的操作(将重复的数据进行过滤)

第五步做集合 排序的操作(将集合数据按照升序排列)

快速入门

public static void main(String[] args) {

    ArrayList<String> one = new ArrayList<>();

    Collections.addAll(one,"河北省","山西省","吉林省","辽宁省","黑龙江省","陕西省","甘肃省","青海省","山东省","福建省","浙江省","台湾省","河南省","湖北省","湖南省","江西省","江苏省","安徽省","广东省","海南省","四川省","贵州省","云南省");


    ArrayList<String> two = new ArrayList<>();

    Collections.addAll(two,"北京市","天津市","上海市","重庆市");


    ArrayList<String> three = new ArrayList<>();

    Collections.addAll(three,"内蒙古自治区","新疆维吾尔自治区","宁夏回族自治区","广西壮族自治区","西藏自治区");


    ArrayList<String> four = new ArrayList<>();

    Collections.addAll(four,"香港特别行政区","澳门特别行政区");



    Stream<String> sm1 = Stream.concat(one.stream(), two.stream());

    Stream<String> sm2 = Stream.concat(three.stream(), four.stream());

    long count = Stream.concat(sm1, sm2).filter(s -> s.length() == 3).count();

    System.out.println("xxcount = " + count);

}

第02节 常用API

获取流的操作
在这里插入图片描述

常用方法
在这里插入图片描述

说明:

    终结:操作完毕之后,不再是 Stream 流对象。
    中间:操作完毕之后,还是 Stream流对象,还可以继续调用 Stream流当中的方法。
    收集:操作完毕之后,可以将 Stream流转换成为集合对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值