Java8 新特性使用

2023-11-06

lamda接口语法

lamda表达式本质:作为接口的一个实例

内置函数式接口

函数式接口 参数类型 返回类型 用途
Consumer<T,> T void void accept(T t)
Supplier<T ,> T T get()
Function<T,R > T R R accept(T t)
Predicate<T, > T boolean boolean test(T t)
BiFunction<T,U,R > T,R U R apply(T t,U u)
UnaryOperator<T, > T T T apply(T t)
BinaryOperator<T, > T,T T T apply(T t1,T t2)
BiConsumer<T, U> T,U void void accept(T t,U u)
BiPredicate<T, U> T,U boolean boolean test(T t,U u)
ToIntFunction<T,> T int 计算int值
ToLongFunction<T,> T long 计算long值
ToDoubleFunction<T,> T double 计算double值
IntFunction<R,> int R 为int计算 返回R类型
LongFunction<R,> long R 为long计算 返回R类型
DoubleFunction<R,> double R 为double计算 返回R类型

方法引用

语法

  • 对象::非静态方法
  • 类::静态方法
  • 类::非静态方法

使用要求

  1. 当要传递给Lambda表达式体的操作,已经有实现的方法了,可以使用
  2. (对象::非静态方法)(类::静态方法)这两种情况接口中的抽象方法要和已实现的方法的形参列表和返回值类型都相同
//对象::方法
    public static void main(String[] args) {

        // void accept(T t) 
        Consumer<String> consumer = str-> System.out.println(str);

        //System.out = PrintStream 对象
        // void println (String x)
        Consumer<String> consumer2 = System.out::println;
        
    }
//类::静态方法
    public static void main(String[] args) {
        //int compare(T o1, T o2);
        //就一行可以隐藏return 和大括号
        //Comparator<Integer> com = (x,y)-> {return Integer.compare(x,y);};
        Comparator<Integer> com = (x,y)-> Integer.compare(x,y);

        //int compare(int x, int y)
        Comparator<Integer> com1 = Integer::compare;
    }
 //类::实例方法
    public static void main(String[] args) {


        BiPredicate<String,String> predicate = (x,y)->x.equals(y);
        //两个参数。第一个参数作为被调用的对象,第二个对象为方法的传参
        BiPredicate<String,String> predicate1 = String::equals;


        //R accept(T t) 传入Dog 对象 返回String
        Function<Dog,String> f = x-> x.getName();

        //因为getName不需要参数
        Function<Dog,String> f2 = Dog::getName;
    }

    class Dog {
        private String name;
        public String getName() {
            return name;
        }

构造器引用以及数组引用

构造器引用

  • 语法 类::new
public class test {
    //构造器引用(主要看接口的抽象方法和哪个构造方法相同)
    public static void main(String[] args) {

        //无参构造(根据Supplier接口,无参。自动匹配到无参构造函数)
        Supplier<Dog> supplier = ()-> new Dog();
        Dog dog = supplier.get();
        Supplier<Dog> supplier1 = Dog::new;
        Dog dog1 = supplier1.get();

        //一个参数构造器(Function需要一个参数,匹配到一个参数对应类型的构造方法)
        Function<String,Dog> f = name-> new Dog(name);
        Dog ck = f.apply("ck");
        Function<String,Dog> f1 = Dog::new;
        Dog ck1 = f1.apply("ck");

        //多个构造参数(匹配到多个参数)
        BiFunction<String,Integer,Dog > biFunction = (name,age)->new Dog(name,age);
        Dog ck2 = biFunction.apply("ck", 100);
        BiFunction<String,Integer,Dog > biFunction1 = Dog::new;
        Dog ck3= biFunction1.apply("ck", 100);
    }

    static class Dog {
        private String name;
        private Integer age;

        public Dog(){};

        public Dog(String name) {
            this.name = name;
        }

        public Dog(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    }
}

数组引用

  • 语法 String[]::new
  Function<Integer,String[]> f = leng-> new String[leng];
  String[] apply = f.apply(10);
  Function<Integer,String[]> f1 = String[]::new;
  f1.apply(10);

Stream流

在这里插入图片描述

串行流和并行流

list.stream();//串行流,俺顺序遍历
list.parallelStream();//并行流,多线程随机获取值

串行流并行流使用

创建Stream流的四种方式

 public static void main(String[] args) {
        //1.集合
        List<Integer> list = new ArrayList<>();
        Stream<Integer> stream = list.stream();
        //2.数组
        int[] array = {1,2,3,4,5,6,7};
        long[] array1 = {1L,2L,3L,4L,5L,6L,7L};
        double[] array2 = {1.1,2.1,3.1,4.1,5.1,6.1,7.1};
        Integer[] array3 = {1,2,3,4,5,6,7};
        //对应的Int long double 返回 IntStream,LongStream,DoubleStream,只有这三个基本数据类型
        IntStream stream1 = Arrays.stream(array);
        LongStream stream2 = Arrays.stream(array1);
        DoubleStream stream3 = Arrays.stream(array2);
        Stream<Integer> stream4 = Arrays.stream(array3);//对象
        //3. Stream.of
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
        //4. 无限流,用来造数据
        // public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        //UnaryOperator 参数T 返回值T
        Stream.iterate("s",x->x+"s").limit(10).forEach(System.out::println);
        Stream.iterate(1,x->x+2).limit(10).forEach(System.out::println);//1,3,5,7...19
        //public static<T> Stream<T> generate(Supplier<? extends T> s)
        //Supplier =》 T get();
        Stream.generate(Math::random).limit(10).forEach(System.out::println); //随机十个数
    }

流的形式

  1. 带泛型的流 Stream<T,>
  2. 基本类型流 IntStream,LongStream,DoubleStream
简述
Stream<T,> collect提供了便捷的Collectors快速收集,没有求和平均值的终端操作,但是在Collectors中有提供对应的方法,求最大最小要提供比较器,提供了方法可以转换成基本类型流
IntStream,LongStream,DoubleStream collect只能使用三个参数来自己定义如何收集,有求和,平均值等终端操作,最大最小不用提供比较器,提供了装箱方法转换成泛型形式的流

中间操作

惰性处理,中间操作只有在终端操作时一次性执行。

筛选和切片

方法 描述
filter(Predicate p) 接受lambda(boolean test(T t)),排除某些元素
distinct() 筛选,通过流元素的hashCode()和equals()去重
limit(long n) 截断流,取前n个
skip(long n) 跳过前n个元素,不足则返回一个空流

映射

方法 描述
map(Function f) 接受lambda(R apply(T t)),对每一个元素进行操作,返回的R没指定,可以是任意元素
mapToDouble(ToDoubleFunction f) 接受lambda(double applyAsDouble(T value)),对每一个元素进行操作
mapToInt(ToIntFunction f) 接受lambda(int applyAsInt(T value))同上
mapToLong(ToLongFunction f) 接受lambda(long applyAsLong(T value))同上
flatMap(Function f) 接受lambda(Function<T, ? extends Stream>)将流中的每个值都换成另一个流,然后将所有流连成一个流

flatMap的使用

public static void main(String[] args) {
        //flatMap使用例子
        String[] strings = {"Hello","world"};
        //输出Helloworld
        //1. x->x.split("") 得到两个String[]数组 {"H","e","l","l","o"},{"w","o","r","l","d"}
        //2. flatMap(x->Arrays.stream(x)) 将每个数组又转换成两个流 {"H","e","l","l","o"}流,{"w","o","r","l","d"}流
        //3. 最后两个流合并 {"H","e","l","l","o","w","o","r","l","d"}
        Arrays.stream(strings).map(x->x.split("")).flatMap(x->Arrays.stream(x)).forEach(System.out::print);
    }

参考:flatMap的使用

排序

方法 描述
sorted() 产生一个新流,其中按自然顺序排序
sorted(Comparator com) 产生一个新流,其中按比较器排序

sorted() 排序的类要实现Comparable接口,不然报错

终止操作

匹配与查找

Predicate =》boolean test(T t)

方法 描述
allMatch(Predicate p) 检查是否匹配所有元素
allMatch(Predicate p) 检查是否至少匹配一个元素
allMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回任意元素
public static void main(String[] args) {
        
        Integer[] strings = {1,4,5,6,7,2,3};
        boolean a = Arrays.stream(strings).allMatch(x -> x < 0); //是否有所元素都小于0 false
        boolean b = Arrays.stream(strings).anyMatch(x -> x < 0); //是否任意一个元素小于0 false
        boolean c = Arrays.stream(strings).noneMatch(x -> x < 0);//是否所有元素都不小于0 true
        Optional<Integer> any = Arrays.stream(strings).findAny();//Optional 里面是1
        Optional<Integer> first = Arrays.stream(strings).findFirst();//Optional 里面是随机一个数
    }

规约

BinaryOperator =>T apply(T t1, T t2)

方法 描述
T reduce(T iden,BinaryOperator b) 可以将流中元素反复结合起来,得到一个值返回T,iden为任意对象作为初始对象
Optional<T,> reduce(BinaryOperator<T,> accumulator) 可以将流中元素反复结合起来,得到一个值返回Optional<T,>,没有初始对象
U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U,> combiner); 可以将流中元素反复结合起来,第三个参数为并行流才生效,表示并行流合并时的操作

备注:经常和map合用

public static void main(String[] args) {
    
        Integer[] strings = {1,4,5,6,7,2,3};
        Integer reduce = Arrays.stream(strings).reduce(6, (x, y) -> x + y); //34
        Optional<Integer> reduce2 = Arrays.stream(strings).reduce((x, y) -> x + y); //28
        //对象使用 求dog的age总和
        ArrayList<Dog> dogs = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            dogs.add(new Dog(i+50));
        }
        Integer reduce3 = dogs.stream().map(x -> x.getAge()).reduce(0, (x, y) -> x + y);//260
        Dog reduce1 = dogs.stream().reduce(new Dog(50), (x, y) -> new Dog(x.getAge() + y.getAge()));//dog对象 其中age=310
        Optional<Dog> reduce4 = dogs.stream().reduce((x, y) -> new Dog(x.getAge() + y.getAge()));//Optional对象
    }
    static class Dog
    {
        private Integer age;

        public Dog(Integer age) {
            this.age = age;
        }

        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
    }

收集

将得到的流收集成对应的类型

方法 描述
collect(Collector c) 将流转换为其他形式,接受一个Collector接口的实现,用于给Stream中元素做汇总的方法(只存在Stream类型中,基本类型IntStream,LongStream,DoubleStream没有这个)
collect(Supplier<R,> supplier,ObjIntConsumer<R,> accumulator,BiConsumer<R, R> combiner) 根据一定规则收集(IntStream,LongStream,DoubleStream)
collect(Supplier<R,> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner) 根据一定规则收集(Stream)

Collectors 类提供了很多静态方法:
方法以及例子

按规则收集例子:

  1. 第一个参数:Supplier<R.> supplier 代表用什么东西收集 返回值确定类型R
  2. 第二个参数: BiConsumer<R, ? super T> 代表要如何处理一个个的元素。 R类型已由第一个参数确定,T为收集到的元素。
  3. 第三个参数:BiConsumer<R, R> 代表要怎么整合前面处理好的一个个元素
  4. 先创建一个容器,然后流中的每个元素如何存进这个容器,流中的每一个元素都会有一个容器,最后所有的容器如何整合起来
int[] a = {1,23,4,5,6,7,8};

//collect2 等价于 collect2_1
HashMap collect2 = Arrays.stream(a).collect(() -> new HashMap(), (x, y) -> x.put(y, y), (x, y) -> x.putAll(y));
HashMap collect2_1 = Arrays.stream(a).collect(HashMap::new, (x, y) -> x.put(y, y), HashMap::putAll);
//collect3 等价于 collect3_1
ArrayList collect3 = Arrays.stream(a).collect(() -> new ArrayList(), (x, y) -> x.add(y, y), (x, y) -> x.addAll(y));
ArrayList collect3_1 = Arrays.stream(a).collect(ArrayList::new, (x, y) -> x.add(y, y), ArrayList::addAll);

Optional类

创建Optional类对象的方法

方法 描述
Optional.of(T t) 创建一个Optional实例,t必须为非空
Optional.empty() 创建一个空的Optional实例
Optional.ofNullable(T t) 创建一个Optional实例,t可以为空

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

方法 描述
boolean isPresent() 判断是否包含对象
void ifPresent(Consumer<? super T> action) 不为空,执行Consumer接口(void apply(T))的实现,参数为该值
void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) 不为空,执行Consumer接口(void apply(T))的实现,参数为该值。否则执行Runnable(void run() 无参无返回) 的实现

获取Optional容器中的对象

方法 描述
T get() 获取对象,空的话报异常(throw new NoSuchElementException(“No value present”);)
T orElse(T other) 如果有值将其返回,没有值返回other,但是不管有没有值都会执行other
T orElseGet(Supplier<? extends T> supplier(无参返回T)) 如果有值将其返回,没有值返回other,只有在为空时才会执行supplier
T orElseThrow() 如果有值将其返回,没有值抛出默认异常(throw new NoSuchElementException(“No value present”);)
T orElseThrow(Supplier<? extends X> exceptionSupplier (无参返回X)) 如果有值将其返回,没有值抛出由Supplier中方法抛出的异常
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java8 新特性使用 的相关文章

随机推荐

  • APP上架需要的准备和流程

    一上架iOS应用市场前的准备 1 选择适合自己的苹果开发者账号 1 个人账号 Individual 费用99美金一年 该账号在App Store销售者只能显示个人的ID 比如zhitian zhang 单人使用 个人账号只能有一个开发者 1
  • IDEA 导入Spring源码:找不到InstrumentationSavingAgent

    错误如下 Error 26 38 java 找不到符号 符号 类 InstrumentationSavingAgent 位置 程序包 org springframework instrument 解决方法 导入项目时选择 Use local
  • 记录vue.config.js中配置代理(devServer)不生效的坑(跨域问题处理)

    前后端分离后 会遇到跨域问题 导致后端响应的数据被浏览器 拦截 前端无法接收 往往就会导致类似下面的问题产生 大意就是请求地址不同源 导致了跨域问题 解决方法 使用vue cli脚手架 在vue config js文件中配置代理服务器 从而
  • canvas视频截图

    const videoEle document createElement video console log videoEle gt videoEle videoEle src https cn ph new rad q s3 cn no
  • easyexcel使用教程-导出篇

    easyExcel使用教程 导出篇 开始准备工作 1 导入Maven依赖
  • 恒合仓库 - 用户管理、用户列表、为用户分配角色

    文章目录 用户管理 一 用户列表 1 1 实体类 1 1 1 分页实体类 1 1 2 用户信息实体类 1 2 业务实现 1 2 1 UserMapper 1 2 2 Service层 1 2 3 Controller层 1 2 4 效果图
  • 【Locomotor运动模块】攀爬

    文章目录 一 攀爬主体 伪身体 1 伪身体 的设置 2 伪身体 和 真实身体 为什么同步移动 3 伪身体 和 真实身体 碰到墙时不同步的原因 现象 原因 解决 二 攀爬 1 需要的组件 伪身体 Climbing Climbable及Inte
  • LeetCode5359.最大的团队表现值——小顶堆与PriorityQueue

    文章目录 引入 解法 引入 在本周周赛中 有这么一道题 公司有编号为 1 到 n 的 n 个工程师 给你两个数组 speed 和 efficiency 其中 speed i 和 efficiency i 分别代表第 i 位工程师的速度和效率
  • 谷歌新一轮裁员,云计算部门 50 人首当其冲

    By 超神经 内容一览 近日 谷歌云计算部门传出裁员消息 称为了调整对国际市场的关注 将进行小规模的人员调整 虽然具体人数尚未公布 但知情消息透露约有 50 人会受到波及 在 2020 年度首次裁员的背后 又反映了谷歌在云计算市场怎样的处境
  • R语言中变量命名规则与反引号的使用

    反引号是针对不符合命名规则的变量名 参数名使用的 那么什么是命名规则呢 变量名称可包含英文字母 数字 下划线和英文点号 句号 所以不能有中文 空格 存在哦 不能以数字或下划线开头 开头必须是英文字母或者点 可以以点号开头 但点号后面的符号不
  • Django项目实现9.1匹配系统出现AttributeError: ‘LocMemCache‘ object has no attribute ‘keys‘

    一般出现这种问题是代码的错误 不能将其作为字典使用 然而我仔细检查了代码报错行后没有发现错误 因为y总说的是用cache key函数 我突然想起早期使用python3manage py shell时候 在acapp下的manage py操作
  • 青春看似荒唐

    知道吗 下雨了 你喜欢的花开了 如此坚强 雨伞在 门把上 楼下送走了新娘 美丽 就像你一样 我曾如此奢望 一路风霜能与你分享 又害怕会这样 依赖着 直到有一天 我们不再疯狂 请不要失望 哪怕平淡收场 青春看似荒唐 没人会选择投降 我懂你的倔
  • 我的第一次面试

    就在昨天 我进行了第一次人生中第一次 以前也面试过 但是都是在学校内 去公司面试 首先他叫到我的时候我就很激动 我觉得我要紧张了 叫到我 我就跟着面试官进了一个房间 房间里面还有一个类似阳台那样一小块地方 一边是窗外 其他都是玻璃墙 我进去
  • 二叉树知识

    二叉树有两种主要的形式 满二叉树和完全二叉树 满二叉树 如果一颗二叉树只有度为0和度为2 并且度为0的节点都在同一层的二叉树就是满二叉树 这棵二叉树为满二叉树 也可以说深度为k 有2 k 1个节点的二叉树 完全二叉树 在完全二叉树 1 除了
  • 自动化测试框架selenium之webdriver

    目录 1 webwebdriver API 1 1 元素的定位 1 2 操作测试对象 1 3 添加等待 1 4 打印信息 1 5 浏览器的操作 1 6 键盘事件 1 7 鼠标事件 1 8 定位一组元素 1 8 多层框架的定位 1 8 多层窗
  • share memory 小结(qualcom )

    QUALIOMM 的AP和MODEM之间的share memory通过把共享内存的空间分成N个不定长的数据块 其中SMEM HEAP INFO记录每个数据块的地址信息 是否已经分配等 只能一个宿主先分配 当然SMEM HEAP INFO 本
  • 解决JPA中使用@Query注解无法使用limit分页函数__一蓑烟雨任平生

    项目中有使用到Spring Data JPA来做查询 在某个查询中 想用limit函数分页 如下 Transactional Query value select a id a even a createat a iot a reada f
  • 百度富文本编辑器插入html代码,百度富文本编辑器插入html代码

    Django 的富文本编辑器 想要用 首先 下载 pip install django tinymce 创建应用 python manage py startapp task 1 引入资源 2 显示UI 我做了一个文章管理的系统 使用到了百
  • Could not find an installed version of Gradle either in Android Studio, or on your system to install

    前言 在使用cordova时 要将html打包成安卓的apk 然后报错这个 这个是需要装gradle 下载入口 因为是高版本兼容低版本 所以随便下载个我用6 4的 步骤 1 下载gradle 2 添加环境变量 此电脑 gt 属性 gt 高级
  • Java8 新特性使用

    文章目录 lamda接口语法 内置函数式接口 方法引用 语法 使用要求 构造器引用以及数组引用 构造器引用 数组引用 Stream流 串行流和并行流 创建Stream流的四种方式 流的形式 中间操作 筛选和切片 映射 排序 终止操作 匹配与