JAVA8函数式编程

JAVA8函数式编程

因为在写业务代码时写了很多的循环筛选语句,而JAVA8提供了函数式编程的方法,支持对集合框架的stream处理,大大简化了代码,学习了一下,总结如下。

1、什么是函数式编程
函数式编程指的是一种编程范式,它将计算描述为一种表达式求值,函数式编程关心的是数据(代数结构的映射关系)。
函数式编程中的函数不是指命令式编程中的函数,而是指数学中的函数,即自变量的映射(一种东西和另一种东西之间的对应关系)。也就是说,一个函数的值仅决定于函数参数的值,不依赖于其他状态。
2、JAVA8中的函数式编程
1) Lambda表达式:JAVA8为支持函数式编程引入的新语法,而为了支持lambda表达式,才有了函数式接口。
2)函数式接口:指的是有且只有一个未实现方法的接口,一般通过FunctionalInterface这个注解来表明某个接口是一个函数式接口。函数式接口是Java支持函数式编程的基础。

lambda表达式例子:
以建立线程为例,JAVA8之前建立线程通常的写法是这样的:

new Thread(new Runnable(){
            @Override
            public void run(){
                System.out.println("Hello world");
            }
        }).start();

使用lambda表达式后:

new Thread(()->System.out.println("Hello Helleo")).start();

lambda表示式解析:
一般形式:
(parameter1,parameter2…parametern)->{函数体}

  • 输入:->前面的部分,即被()包围的部分。可以有0个到多个参数,如两个参数时写法:(a, b);当然也可以没有输入,此时直接就可以是()。
  • 函数体:->后面的部分,即被{}包围的部分;可以是一段代码。
  • 输出:函数式编程可以没有返回值,也可以有返回值。如果有返回值时,需要代码段的最后一句通过return的方式返回对应的值。

如果函数体里只有一个语句的时候,可以省略掉{}。

JAVA提供常见的几种函数式编程的接口:

  1. Supplier: 数据提供器,可以提供 T 类型对象;无参的构造器,提供了 get 方法;
  2. Function<T,R>: 数据转换器,接收一个 T 类型的对象,返回一个 R类型的对象; 单参数单返回值的行为接口;提供了 apply, compose, andThen, identity 方法;
  3. Consumer: 数据消费器, 接收一个 T类型的对象,无返回值,通常用于设置T对象的值; 单参数无返回值的行为接口;提供了 accept, andThen 方法;
  4. Predicate: 条件测试器,接收一个 T 类型的对象,返回布尔值,通常用于传递条件函数; 单参数布尔值的条件性接口。提供了 test (条件测试) , and-or- negate(与或非) 方法。

函数式编程的使用:
先来了解一下JAVA8中的Stream,Stream是Java 8新增的接口,Stream可以认为是一个高级版本的 Iterator。它代表着数据流,流中的数据元素的数量可以是有限的,也可以是无限的。
Stream跟Iterator的差别是:

  • 无存储:Stream是基于数据源的对象,它本身不存储数据元素,而是通过管道将数据源的元素传递给操作。
  • 函数式编程:对Stream的任何修改都不会修改背后的数据源,比如对Stream执行filter操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新的Stream。
  • 延迟执行:Stream的操作由零个或多个中间操作(intermediate operation)和一个结束操作(terminal operation)两部分组成。只有执行了结束操作,Stream定义的中间操作才会依次执行,这就是Stream的延迟特性。
  • 可消费性:Stream只能被“消费”一次,一旦遍历过就会失效。就像容器的迭代器那样,想要再次遍历必须重新生成一个新的Stream。

Stream对象的创建
1)创建空的Stream对象

 Stream stream = Stream.empty();

2 通过集合类的stream或者parallelStream方式创建

List<Integer> list = Arrays.asList(1,2,3,4,5);
//串行处理的Stream对象
Stream IntegerStream = list.stream();
//并行处理的Stream对象
Stream parallelStream = list.parallelStream();

3)通过Stream类中的of方法创建

Stream s1 = Stream.of("tttt", "dddd", "cccc", "dooo");

常见的Stream的操作:
forEach():使用该方法迭代流中的每个数据
例子:

List<Student> list = Arrays.asList(
                // name,age
                new Student("李丽", 19),
                new Student("王浩", 20),
                new Student("王宇", 18),
                new Student("张路", 17),
                new Student("李明", 22),
                new Student("李之为", 25),
                new Student("李寒", 21)
        );
        list.forEach(student -> System.out.println(student));

    }
}
      class Student{
                private String name;
                private int age;

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

                public String getName() { return name; }

                public void setName(String name) { this.name = name; }

                public int getAge() { return age; }

                public void setAge(int age) { this.age = age; }
                
                @Override
                public String toString(){
                    return this.getName()+"   "+this.getAge();
                }

控制台输出
在这里插入图片描述
sorted() :使用该方法排序数据

list.stream().sorted((student1,student2)->student1.getAge()-student2.getAge()).forEach(student -> System.out.println(student));

一行代码就可以解决。
控制台输出
未排序前
在这里插入图片描述
排序后
在这里插入图片描述
filter():过滤操作

list.stream().filter((student) -> student.getAge() > 20).forEach(student -> System.out.println(student));

未过滤前
在这里插入图片描述
过滤后
在这里插入图片描述
limit:使用该方法截取原Stream

list.stream().limit(3).forEach(student -> System.out.println(student));

未截断前
在这里插入图片描述
截断后
在这里插入图片描述
skip():与limit互斥,使用此方法跳过元素

list.stream().skip(2).forEach(student -> System.out.println(student));

跳过前
在这里插入图片描述
跳过后:
在这里插入图片描述

distinct():使用该方法去重,注意:必须重写对应泛型的hashCode()和equals()方法****

 List<Student> list = Arrays.asList(
                // name,age
                new Student("李丽", 19),
                new Student("王浩", 20),
                new Student("王宇", 18),
                new Student("张路", 17),
                new Student("李明", 22),
                new Student("李之为", 25),
                new Student("李寒", 21),
                new Student("李丽",25),
                new Student("李明",21)

        );


        list.stream().distinct().forEach(student -> System.out.println(student));
 class Student{
                private String name;
                private int age;

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

                public String getName() { return name; }

                public void setName(String name) { this.name = name; }

                public int getAge() { return age; }

                public void setAge(int age) { this.age = age; }

                @Override
                public String toString(){
                    return this.getName()+"   "+this.getAge();
                }

                @Override
                public int hashCode(){
                    return 1;
                }

                @Override
                public boolean equals(Object stu){
                    Student student = (Student)stu;
                    return  this.name.equals(student.getName());
                }

去重前
在这里插入图片描述
去重后
在这里插入图片描述
max,min,sum,avg,count :聚合操作

IntSummaryStatistics intSummaryStatistics = list.stream().mapToInt(s -> s.getAge()).summaryStatistics();
        //学生人数
        System.out.println("count:" + intSummaryStatistics.getCount());
        //学生平均年龄
        System.out.println("average:" + intSummaryStatistics.getAverage());
        //学生中的最大年龄
        System.out.println("maxAge:" + intSummaryStatistics.getMax());
        //学生中的最小年龄
        System.out.println("minAge:" + intSummaryStatistics.getMin());
        //学生的年龄总和
        System.out.println("sumAge:" + intSummaryStatistics.getSum());

在这里插入图片描述
map():接收一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

 List<String> strList = Arrays.asList("abd","rgt","uudj","ssee");
        System.out.println("转化前");
        strList.stream().forEach(str->System.out.println(str));
        System.out.println("转化后");
    

List<String> transStrList = strList.stream().map(str->str.toUpperCase()).collect(toList());
    transStrList.stream().forEach(str->System.out.println(str));

控制台输出
在这里插入图片描述
**collect(toList()):**将Stream转换成List

List<String> transStrList = strList.stream().map(str->str.toUpperCase()).collect(toList());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值