Java SE(十四)之 Java 8新特性(Lambda,Stream流,方法引用等)

Java 8

Java8可以是一个里程碑的版本,提供了很多有用的特性。

Lambda

1.概述

作用:简化匿名内部类的代码写法

首先回顾一下匿名内部类:
(为什么要引入匿名内部类?是因为可以方便创建子类对象,最终目的是为了简化代码编写,具体可以指路:匿名内部类

// 首先创建一个接口
interface inter{
    public void eat();
}

public class AnonymousDemo
{
	public static void main(String[] args) {
	// 直接使用匿名内部类,重写eat方法并调用
        new inter(){
            @Override
            public void eat() {
                System.out.println("正在调用eat方法");
            }
        }.eat();
    }
}

但是,Lambda看到这里还是觉得不够简便,所以进一步开始简化!

Lambda语法:

( parameter-list ) -> { expression-or-statements }
注:-> 是语法形式,无实际含义

所以上面的可以简化成:

interface inter{
    public void eat();
}
public class AnonymousDemo {
    public static void main(String[] args) {
        // 这里的eat函数没有参数,另外实现语句只有一句,就省略{}
        inter myInter = () -> System.out.println("正在调用eat方法");
        myInter.eat(); // 调用eat方法
    }
}

Lambda表达式本身就是一个接口的实现,Lambda表达式只能简化函数式接口的匿名内部类的写法形式

什么是函数式接口?
首先必须是接口、其次接口中有且仅有一个抽象方法的形式
常会在接口上加上一个@FunctionalInterface注解,标记该接口必须是满足函数式接口

最后用两张图进行Java8 和Java7的对比,参考https://www.zhihu.com/question/20125256/answer/324121308

第一张图,和上面的例子很像,原本java7必须得按照面向对象那套流程;而Java 8的Lambda可以直接将接口的实现赋值给一个变量。
在这里插入图片描述

第二张图,是说明上面那个“变量”可以当作参数传给其他函数(传统的Java 7必须要求定义一个实现类)

在这里插入图片描述

2.应用场景

直接通过几种不同场景来熟悉Lambda

借用线程中的接口来演示一下
(1)无参数,无返回体

() -> System.out.println("零参数 lambda");

(2)一个参数,无返回值

// 实现Function接口
Function<Integer, Integer> add = (x) -> x + 1;
int result = add.apply(5); // result = 6

(3)两个参数,有返回值

public static void findMaxValue(int num1,int num2){
        Comparator<Integer> comparatorMax = (o1, o2) ->{
            log.info("o1:{}",o1);
            log.info("o2:{}",o2);
            return (o1<o2)? o2 :(o1);
        };
        log.info("findMaxValue:{}",(comparatorMax.compare(num1,num2)));
    }

3.省略规则

  • 参数类型可以省略不写(编译器会根据上下文判断)
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略。
  • 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号!

Stream流

1. 简介

在这里插入图片描述

作用:用来简化数组和集合的操作

简单说就是 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等

可以先看一个小例子:

要求是:创建一个集合,存储多个字符串元素,把集合中所有以"张"开头的元素存储到一个新的集合,把"张"开头的集合中的长度为3的元素存储到一个新的集合最后遍历

如果按照正常编程,可能得挨个遍历对元素进行判断处理,但是Stream编程就可以一步到位

public class StreamDemo {
    public static void main(String[] args) {
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良"));

        //Stream流
        list1.stream().filter(s->s.startsWith("张"))
                .filter(s->s.length() == 3)
                .forEach(s-> System.out.println(s));
    }
}

Stream流的主要构成(三类方法)

  • 获取Stream流:创建一条流水线,并把数据放到流水线上准备进行操作
  • 中间方法:流水线上的操作,一次操作完毕后,还可以继续进行其他操作
  • 终结方法:一个Stream流只能有一个终结方法,是流水线上最后一个操作

下面将对三个组成进行分别介绍

2. Stream流的创建

Stream操作集合或者数组的第一步是先得到Stream流,然后才能使用流的功能。

(1)Collection集合获取Stream流的方式

可以使用Collection接口中的默认方法stream()生成流

// 获取当前集合对象的Stream流
default Stream<E> stream()

(2) Map体系集合

把Map转成Set集合,间接的生成流

(3)数组获取Stream流的方式

通过Arrays中的静态方法stream生成流

方法含义
public static Stream stream(T[ ] array)获取当前数组的Stream流
public static Stream of(T… values)获取当前数组/可变数据的stream流
public class StreamDemo {
    public static void main(String[] args) {
        //Collection体系的集合可以使用默认方法stream()生成流
        List<String> list = new ArrayList<String>();
        Stream<String> listStream = list.stream();

        //Map体系的集合间接的生成流
        Map<String,Integer> map = new HashMap<String, Integer>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<Integer> valueStream = map.values().stream();
        Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

        //数组可以通过Arrays中的静态方法stream生成流
        String[] strArray = {"hello","world","java"};
        Stream<String> strArrayStream = Arrays.stream(strArray);
}

3. 常用中间方法

方法含义
stream filter(Predicate< ? super T> predicate)用于对流中的数据进行过滤
stream limit( long maxsize)获取前几个元素
stream skip(long n)跳过前几个元素
stream distinct( )去除流中重复的元素。依赖(hashCode和equals方法)
static stream concat(Stream a,Stream b)合并a和b两个流为一个流

中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程

在Stream流中无法直接修改集合、数组中的数据

4. 常用终结方法

方法含义
void forEach(Consumer action)对此流的每个元素执行遍历操作
long count()返回此流中的元素数

终结操作方法,调用完成后流就无法继续使用了,原因是不会返回Stream了

5. 收集Stream流

把Stream流操作后的结果数据转回到集合或者数组中去

方法名说明
R collect(Collector collector)把结果收集到集合中

具体收集方法(Collector工具类):

方法名说明
public static Collector toList()把元素收集到List集合中
public static Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中

方法引用

1.方法引用符 ::

2.引用类方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值