首页 > 其他分享 >jdk1.8新特性——lamdba表达式

jdk1.8新特性——lamdba表达式

时间:2024-03-16 09:58:23浏览次数:34  
标签:jdk1.8 String stream lamdba System println public 表达式 out

  • 如果方法有返回值且方法体中只有return这一行代码,return可省略,如果不写,必须随同花括号一起省略
public class Test01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestInterface testInterface = (a,b) -> a+b;
        System.out.println(testInterface.add(2,3)); //5
        TestInterface2 testInterface2 = a -> System.out.println(a + 1);
        testInterface2.m1(3); //4
    }
}

@FunctionalInterface
interface TestInterface{
    int add(int a,int b);
}

@FunctionalInterface
interface TestInterface2{
    void m1(int a);
}

JDK提供的四大函数式接口

Suplier<T> 无参有返回值

Consumer 一个参数无返回值

Predicate<T> 一个参数返回boolean类型

Function<T,R> 一个参数有返回值

public class Test01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //无参有返回值
        Supplier<Integer> supplier = () -> 1;
        System.out.println(supplier.get()); //1

        //有参返回布尔
        Predicate<Integer> predicate = (a) -> a > 5 ? true:false;
        System.out.println(predicate.test(6)); //true

        //一个参数无返回值
        Consumer<Integer> consumer = a -> System.out.println(a);
        consumer.accept(1); //1

        //有参数有返回值
        Function<Integer,Integer> function = a -> a + 1;
        System.out.println(function.apply(1)); //2

    }
}

lamdba表达式引用方法

我们可以使用lamdba表达式的接口指向一个已经被实现过的方法(就是有方法体的方法)

语法:

方法归属者::方法名

    • 静态方法的归属者为类名
    • 实例方法的归属者为对象
public class Test01 {
    public static void main(String[] args){
        Function<Integer,Integer> fun = Test01::doubleNum;
        System.out.println(fun.apply(3)); //6
        Function<Integer,Integer> fun1 = new Test01()::doubleNum2;
        System.out.println(fun1.apply(4)); //8
    }

    public static int doubleNum(int num){
        return num*2;
    }

    public int doubleNum2(int num){
        return num*2;
    }
}
当函数式接口方法的第一个参数,是实现方法的调用者,并且第二个参数(如果有的话),是需要调用方的参数时(或无参数时)
  • 类型::方法名
public class Test01 {
    public static void main(String[] args){
        Function<String,Integer> fun = str -> str.length();
        System.out.println(fun.apply("string")); //6
    }
}
public class Test01 {
    public static void main(String[] args) {
        //第二个参数为第一个参数调用方法的参数
        MyInterface myInterface = BigInteger::add;
        System.out.println(myInterface.m1(new BigInteger("1"), new BigInteger("2")));
    }
}

@FunctionalInterface
interface MyInterface {
    BigInteger m1(BigInteger a,BigInteger b);
}
public class Test01 {
    public static void main(String[] args) {
        MyInterface myInterface = Student::setName;
        myInterface.m1(new Student(),"张三");
        /*我是学生,名字是张三*/
    }
}

class Student {
    private String name;

    public Student() {
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("我是学生,名字是" + name);
    }
}

@FunctionalInterface
interface MyInterface {
    void m1(Student stu,String name);
}

lamdba引用构造方法

public class Test01 {
    public static void main(String[] args) {
        //无参
        StudentBlankCon studentBlankCon = () -> new Student();
        StudentBlankCon studentBlankCon2 = Student::new;
        System.out.println(studentBlankCon.getStu()); //Student{name='Zhangsan', age=1, score=11}
        System.out.println(studentBlankCon2.getStu()); //Student{name='Zhangsan', age=1, score=11}

        //全参,lamdba表达式会根据参数类型的不同调用相关的构造方法
        StudentAllParamCon studentAllParamCon = (name,age,score) -> new Student(name,age,score);
        System.out.println(studentAllParamCon.getStu("Lisi", 12, 90));//Student{name='Lisi', age=12, score=90}
        StudentAllParamCon studentAllParamCon1 = Student::new;
        System.out.println(studentAllParamCon.getStu("Lisi", 12, 90));//Student{name='Lisi', age=12, score=90}
    }
}


class Student {
    private String name = "Zhangsan";
    private int age = 1;
    private int score = 11;

    public Student() {
    }

    public Student(String name, int age, int score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

@FunctionalInterface
interface StudentBlankCon {
    Student getStu();
}
@FunctionalInterface
interface StudentAllParamCon {
    Student getStu(String name, int age, int score);
}

lamdba表达式对线程创建的支持

public class Test01 {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName());
            }
        },"t1");
        t1.start();
    }
}

lamdba表达式操作集合

遍历集合

public class Test01 {
    public static void main(String[] args) {
        //元素遍历
        ArrayList<Integer> arrayList = new ArrayList<Integer>();

        //使用Collections工具类批量添加元素
        Collections.addAll(arrayList,1,2,3,4,5,6,7,8,9);

        //lamdba表达式遍历集合 forEach(Consumer 自带函数式接口,有参无返回值)
        arrayList.forEach( i -> System.out.println(i));
        
        //ladba对System.out.println的支持
        //如果遍历出来的元素以print/println形式打印
        arrayList.forEach(System.out::println);
    }
}

lamdba表达式对print/println的支持

//如果遍历出来的元素以print/println形式打印
arrayList.forEach(System.out::println);

删除集合中的元素

public class Test01 {
    public static void main(String[] args) {
        //元素遍历
        ArrayList<Integer> arrayList = new ArrayList<Integer>();

        //使用Collections工具类批量添加元素
        Collections.addAll(arrayList,10,20,30,40,50,60,70,80,90);
        
        //removeIf(Predicate 内置函数式接口,一个参数有返回值);
        /*arrayList.removeIf(new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer.equals(10);
            }
        });*/
        
        //lamdba简化
        arrayList.removeIf((i) -> i.equals(10));

        System.out.println(arrayList);
    }
}

集合中元素的排序

public class Test01 {
    public static void main(String[] args) {
        //元素遍历
        ArrayList<Item> arrayList = new ArrayList<Item>();

        //使用Collections工具类批量添加元素
        Collections.addAll(arrayList,new Item(1,"牙刷",1.2),new Item(3,"凳子",0.2),new Item(2,"椅子",0.01));

        /*arrayList.sort(new Comparator<Item>() {
            @Override
            public int compare(Item o1, Item o2) {
                return o1.getId()- o2.getId();
            }
        });*/
        //lamdba表达式
        arrayList.sort( (o1,o2) -> o1.getId() - o2.getId() );

        System.out.println(arrayList);
        //[item{id = 1, name = 牙刷, price = 1.2}, item{id = 2, name = 椅子, price = 0.01}, item{id = 3, name = 凳子, price = 0.2}]
    }
}

函数式编程(流式编程)

  • 为了支持函数式编程的接口,为函数式接口
    • 函数式接口,要求只能有一个自己的抽象方法(被注解@FunctionalInterface修饰)
  • 在编写业务的过程中,以纯函数的书写操作流程作为主要的实现方式
  • 面向对象以操作对象为思想核心,而函数式编程是以操作函数实现流程为思想核心,他们的关注点是不同的
  • 函数式编程最标准的实现方式
    • 从以前的数据参数化,转变为行为参数化
      • 以前传入的是数据,现在传入的是行为
        //lamdba表达式
        arrayList.sort( (o1,o2) -> o1.getId() - o2.getId() );
    • 如何行为参数化:lamdba表达式
    • Java语言中的函数式编程完全是由lamdba表达式支持的,而lamdba表达式只能操作函数式接口(只有一个抽象方法的接口),有很强的局限性

Stream流处理集合

  • Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。
    • 用于简化集合/数组操作的API
    • 怎么简化:函数式编程
  • 需求
    • 将一组学生的姓名保存到集合中
    • 从集合中筛选出以z开头的学生的姓名,保存到一个集合中
    • 从集合中筛选出姓名超过10个字符的学生姓名,保存到一个新的集合中。
public class Test01 {
    public static void main(String[] args) {
        //集合创建
        List<String> list = new ArrayList<String>();
        Collections.addAll(list,"zhangsan","zhangguorong","zhangguolao","zhangshaohan","lisi","wangwu");

        //筛选z开头的加入新集合
        List<String> l1 = new ArrayList<String>();

        /*for (String s : list) {
            if (s.startsWith("z")) {
                l1.add(s);
            }
        }*/

        list.forEach((s) -> {
            if (s.startsWith("z")) {
                l1.add(s);
            }
        });
        System.out.println(l1);
        //[zhangsan, zhangguorong, zhangguolao, zhangshaohan]

        //从l1中再次筛选超过10个字符的(用stream流)
        //新建集合
        List<String> l2 = new ArrayList<String>();
        l1.forEach((s) -> {
            if (s.length() > 10) {
                l2.add(s);
            }
        });
        System.out.println(l2);
        //[zhangguorong, zhangguolao, zhangshaohan]


        //使用stream流,经过stream流操作之后,原来的集合list,没有受到影响
        List<String> newList = list.stream().filter(s -> s.startsWith("z")).filter(s -> s.length() > 10).collect(Collectors.toList());
        System.out.println(newList); //[zhangguorong, zhangguolao, zhangshaohan]
        
    }
}
  • 使用Stream流的思想
    • 集合 --> stream流 --> 过滤 -->过滤 --> ... -->forEach打印/转换为新的集合。
  • 操作stream流的三类方法
    • 获取stream流的方法
      • 对于当前案例: list.stream()就获取了stream流
    • 中间方法(处理集合)
      • 好比流水线上的操作,一个步骤完成后及进行下一个步骤,对于当前案例,filter方法就是中间方法用来过滤元素的,中间方法可以有无限多个。
    • 终结方法
      • 流水线上最后一个操作
      • 对于当前案例,就是用collect(Collectors.toList());将Stream转为List集合。
      • 终结方法,只能有一个

集合和数组获取stream流的方式

  • 集合
    • Collection集合获取stream流的方式(List Set) 单列集合
    • 调用stream()方法
Stream<String> stream = new ArrayList<String>().stream();
    • Map集合获取stream流的方式 双列集合
    • 键和值分别处理为stream流
    • 键值对处理为stream流
        Map<String,Object> map = new HashMap<String,Object>();
        
        //将键和值分别处理为stream流
        map.keySet().stream();
        map.values().stream();
        
        //将键值对处理为stream流
        Stream<Map.Entry<String, Object>> stream = map.entrySet().stream();
  • 数组获取stream流的方式
    • 通过Arrays工具类调用Arrays.stream()方法
    • 通过Stream.of()方法
        String[] arr = {"aaa", "bbb", "ccc"};
        
        //方式一,通过Arrays工具类调用Arrays.stream方法
        Stream<String> stream = Arrays.stream(arr);
        
        //方式二,使用Stream.of()方法
        Stream<String> stream1 = Stream.of(arr);
            //重载方法可直接将传入元素,自动生成数组stream
        Stream<String> stream2 = Stream.of("aaa", "bbb", "ccc");

stream流的中间方法

  • limit(long n)从前面提取n个元素
  • skip(long n)排除前面n个元素
  • map()对元素进行加工
  • distinct()去重
  • Stream.concat() 将N组流进行组合,得到新的流
    • 不同泛型的流也可合并,合并后的泛型为他们共同父类或接口
public class Test01 {
    public static void main(String[] args) {
        //集合创建
        List<String> list = new ArrayList<String>();
        Collections.addAll(list,"zhangsan","zhangguorong","zhangguolao","zhangshaohan","lisi","wangwu");

        System.out.println("提取后");
        //提取前两个元素
        list.stream().limit(2).forEach(System.out::println);

        System.out.println("排除后");
        //排除前两个元素
        list.stream().skip(2).forEach(System.out::println);

        //每个元素前加 姓名:
        System.out.println("加工后");
        list.stream().map(s -> "姓名:" + s).forEach(System.out::println);

        //集合的组合
        //生成新的流
        Stream<String> stream1 = Stream.of("aaa", "bbb", "ccc");
        Stream<Integer> stream2 = Stream.of(11,22,33);
        //Serializable允许序列化接口,String和Integer类型都实现了Serializable接口
        Stream<? extends Serializable> result = Stream.concat(stream1, stream2);
        System.out.println("拼接后");
        result.forEach(System.out::println);

        Stream<String> stream = Stream.of("111", "111", "222", "222", "333", "333");
        System.out.println("去重后");
        stream.distinct().forEach(System.out::println);

    }
}

stream流的终结方法

  • forEach 遍历元素
  • count 返回元素的数量,结果为long类型
  • collect 返回新的集合
    • 传入参数
      • Collectors.toList() 返回List
      • Collectors.toSet() 返回Set
  • reduce 返回规约的结果
    • 规约:将N多个数据,进行处理,最终得到一个数据
      • stream规约操作:将stream流中的元素聚合 缩减为单个结果
public class Test01 {
    public static void main(String[] args) {
        //集合创建
        List<String> list = new ArrayList<String>();
        Collections.addAll(list,"zhangsan","zhangguorong","zhangguolao","zhangshaohan","lisi","wangwu");

        //forEach()遍历
        list.stream().filter(s -> s.length() >= 10).forEach(System.out::println);

        //count()返回long类型的长度
        long count = list.stream().filter(s -> s.length() >= 10).count();
        System.out.println("元素数量为" + count);//元素数量为3
        System.out.println("--------------------------------");//元素数量为3

        //coolect()返回新的集合
        list.stream().filter(s -> s.length() >= 10).collect(Collectors.toList());

        //reduce()返回规约的集合
        /*Optional<String> reduce = list.stream().filter(s -> s.startsWith("z")).reduce(new BinaryOperator<String>() {
            @Override
            public String apply(String s, String s2) {
                //s为上一次运算的结果,s2为新加入的元素
                return s + s2;
            }
        });*/
//        reduce配合lamdba
        Optional<String> opt = list.stream().reduce((s, s2) -> s + s2);
//        返回值是一个Optional对象,使用get()直接取得值
        System.out.println(opt.get());//zhangsanzhangguorongzhangguolaozhangshaohanlisiwangwu

    }
}

标签:jdk1.8,String,stream,lamdba,System,println,public,表达式,out
From: https://blog.csdn.net/weixin_44212870/article/details/136727323

相关文章

  • java毕业设计夕阳红养老院系统(springboot+mysql+jdk1.8+meven)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着社会的发展和人口老龄化的加剧,养老问题逐渐成为社会关注的焦点。传统的家庭养老模式已无法满足日益增长的养老需求,特别是对于独居老人和失能老人来说,......
  • 深入理解 Java 多线程、Lambda 表达式及线程安全最佳实践
    Java线程线程使程序能够通过同时执行多个任务而更有效地运行。线程可用于在不中断主程序的情况下在后台执行复杂的任务。创建线程有两种创建线程的方式。扩展Thread类可以通过扩展Thread类并覆盖其run()方法来创建线程:publicclassMyThreadextendsThread{public......
  • Lamda 表达式
    Runable是一个函数接口,再创建线程时可以使用Lamda表达式,下面是Lamda的简化过程publicclassindex{//3.实现静态类staticclassStudent1implementsILike{@Overridepublicvoideat(){System.out.println("student1-eat")......
  • jdk1.8下载与安装 图文版
    JDK下载首先在Oracle官网上下载jdk1.8.https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html,如下图所示,找到jdk1.8,选择对应的版本或者链接:https://pan.baidu.com/s/13lZy7JKE1xn-dXx_VG1QFA?pwd=29wl提取码:29wlJDK安装选择下一步更改......
  • C# 常见的Lambda表达式
    原文链接:https://blog.csdn.net/weixin_57718347/article/details/130384704Lambda表达式是C#中的一种匿名函数,通常用于简化代码和提高效率。以下是一些常见的Lambda表达式:1.基本Lambda表达式:(x)=>x+1;表示接受一个参数x,并返回x+1。2.带多个参数的Lambda表达式:(x,y)=>......
  • Spring Task 定时任务框架 以及cron表达式
    一:SpringTask介绍SpringTask是spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。定位:定时任务框架作用:定时自动执行某段Java代码应用场景:·信用卡每月还款提醒·银行贷款每月还款提醒·火车票售票系统处理未支付订单·入职纪念日为用户......
  • 『LeetCode』10. 正则表达式匹配 Regular Expression Matching
    题目描述给你一个字符串s和一个字符规律p,请你来实现一个支持'.'和'*'的正则表达式匹配。'.'匹配任意单个字符'*'匹配零个或多个前面的那一个元素所谓匹配,是要涵盖整个字符串s的,而不是部分字符串。示例1:输入:s="aa",p="a"输出:false解释:"a"无法匹配"aa"整个字......
  • 实验1 c语言开发环境使用和数据类型、运算符、表达式
    task1`#include<stdio.h>intmain(){printf("o\n");printf("\n");printf("II\n");printf("o\n");printf("<H>\n");printf("II\n");return0;}``#include<stdio......
  • CSharp的lambda表达式匿名类扩展方法
    c#的lamba表达式之前已经写过一些关于委托还有事件的文章,今天就来介绍一下lambda表达式。首先定义需要的函数以及委托{publicdelegatevoidDoNothingDelegate();publicdelegatevoidStudyDelegate(intid,stringname);privatevoidDoNothing(){Console.WriteL......
  • java毕业设计线上水果店系统app(springboot+mysql+jdk1.8+meven)
    本系统(程序+源码)带文档lw万字以上 文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在现代社会,随着生活节奏的加快和健康饮食观念的普及,人们对于水果的需求日益增长。传统的水果购买方式通常需要在实体店铺中进行,这不仅耗费时间,而且在种类......