首页 > 编程语言 >java8新特性理解

java8新特性理解

时间:2023-05-04 21:33:55浏览次数:59  
标签:lamda 函数 int 特性 public 理解 FunctionalInterfaceA java8

一些关于java8新特性理解

引例

在java中,考虑实现按学号顺序对学生List进行排序的功能。

一. java8以前的实现方式:匿名内部类

如果不使用java8的新特性,我们实现该功能通常会使用匿名内部类的方法。

import java.util.*;;

class Student{
    private int id;
    private String name;

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

    public int getId(){
        return this.id;
    }

    public String getName(){
        return this.name;
    }

}


public class Example{
    public void sortStudent(List<Student> students){
        students.sort(new Comparator<Student>() {
            @Override
            public int compare(Student stu1, Student stu2){
                return stu1.getId() - stu2.getId();
            }
        });
    }
}

因为每一次比较时,比较方式是不同的,因此在每一次比较时,我们都是创建了一个Comparator的子类,这个类没有名字,且只有一个实例,这就是匿名内部类,它等效于显式地创建一个Comparator的子类,再传递给sort这个子类的实例。对代码

public class Example{
    public void sortStudent(List<Student> students){
        students.sort(new Comparator<Student>() {
            @Override
            public int compare(Student stu1, Student stu2){
                return stu1.getId() - stu2.getId();
            }
        });
    }
}

我们可以等效地写成

class StudentComparator implements Comparator<Student>{
    @Override
    public int compare(Student stu1, Student stu2){
        return stu1.getId() - stu2.getId();
    }
}


public class Example{
    public void sortStudent(List<Student> students){
        students.sort(new StudentComparator());
    }
}

可以看到,无论是使用匿名内部类还是显式声明的子类,代码都很长,破坏了代码的可读性。java8为了改善这种情况,引入了一系列新特性。

二.函数式编程

在java编程时,有时会希望传入一个方法作为参数来实现某样功能。比如: List.sort(比较方法)中,我们希望传入的比较方法其实就是一个函数。这种将函数作为参数传入的思想被称为函数式编程。

在java中,我们认为“一切皆对象”,所以具体来看,java中List的sort方法声明是sort(Comparator<? super E> c)参数是一个Comparator类的对象,查看Comparator类的源代码,我们发现它只有一个抽象方法(重写的Object类方法equals除外),和平常的接口很不一样,因此我们引入函数式接口的概念。

三.函数式接口

这是java8引进的一个新概念。指的是只有一个抽象方法的接口(除了重写Object类方法以外),通常,这样的方法会被@FunctionalInterface所修饰(不被这个注解修饰,但满足只有一个抽象方法的接口(除了重写Object类方法以外)这一条件的接口也是函数式接口)。下面是一个例子。

@FunctionalInterface
interface FunctionalInterfaceA{
    public int method();
}

四.lamda表达式

lamda表达式是为了简化实现函数式接口匿名内部类的书写而引进的。对于下面的代码

public void test(){
        FunctionalInterfaceA a = new FunctionalInterfaceA() {
            public int method(){
                return 1;
            }
        };
    }

使用lamda表达式就可以写成

public void test(){
        FunctionalInterfaceA a = () -> 1;
    }

注意:lamda表达式在实际上就是创建了一个匿名内部类,但是lamda表达式仅在实现函数式接口的匿名内部类中能使用,若内部类要重写多个方法,是不能用lamda表达式实现的。具体lamda表达式的语法,详见https://www.runoob.com/java/java8-lambda-expressions.html

五.方法引用

观察上面的lamda表达式使用的格式FunctionalInterfaceA a = () -> 1;,我们发现形式上是很类似于变量 = 函数的,这是因为函数式接口FunctionalInterfaceA可以由它的抽象方法 public int method()唯一确定。既然有变量 = 函数的形式,我们自然想到,当两函数的参数列表和返回值相同时,我们可以用一个函数为另一个函数赋值。这就是方法引用的思想。

观察下面的代码

class A{
    private int attr;
    public A(int a){
        attr = a;
    }
    public int methodA(){
        return attr;
    } 
}

class Example{
    public static void main(String[] args) {
        A a = new A(10000);
        FunctionalInterfaceA b = a::methodA;
    }
}

@FunctionalInterface
interface FunctionalInterfaceA{
    public int method();
}

因为A的methodA方法的函数签名与返回值和FunctionalInterfaceA的抽象方法相同,故可以用methodA来代替method,其中的FunctionalInterfaceA b = a::methodA;用lamda表达式可以写为FunctionalInterfaceA b = () -> a.methodA();,更多方法引用的语法,见https://blog.csdn.net/ShuSheng0007/article/details/107562812

六. Stream流

Stream流是java8为了统一集合,数组对其中元素进行变换的操作所引入的新类型,类似python中序列的概念。

Stream中的方法主要分为三类:获取操作,处理操作,终结操作

获取操作主要是为了获取流,比如List.stream(),其返回值是Stream
处理操作主要是对流中的数据进行处理,比如Stream.mapToInt(ToIntFunction<? super T> mapper),其返回值也是Stream,这就可以让Stream能类似管道一样,将多个中间的处理操作进行组合,从而实现较为复杂的操作。
终结操作是将流转为新的类型进行输出,比如Stream.collect(Collector<? super T, A, R> collector),将数据通过不同的收集器收进不同的集合中。

下面举一个将Set<Integer>转为int[]的例子

public int[] set2Array(Set<Integer> set){
        return set.stream().mapToInt(x -> x).toArray();
    }

更多关于Stream的信息,详见https://www.runoob.com/java/java8-streams.html

标签:lamda,函数,int,特性,public,理解,FunctionalInterfaceA,java8
From: https://www.cnblogs.com/tryingWorm/p/17372566.html

相关文章

  • 对于Object中一些方法的疑惑与理解
    getClass这是生成字节码文件对象的三种方式之一,由任意对象调用getClass(Object中定义的方法)可以返回该类的字节码文件对象,一般一般用于反射getName该方法是,Class类中定义的一个方法,用于返回字节码文件对象所表示的实体(类或者接口)的全类名2023.5.4对于向上转型和任何类型都可以......
  • Spring @Scheduled注解的理解
    一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。按顺序依次为:1.秒(0~59)2.分钟(0~59)3.小时(0~23)4.天(月)(0~31,但是你需要考虑你月的天数)5.月(0~11)6.天(星期)(1~71=SUN或SUN,MON,TUE,WED,THU,FRI,SAT)7.年份(1970-2099)在子表达式(月)里表示每个月的含义,“”在子表达式(天(星期))表示星期......
  • 深入理解 Linux 的 I/O 系统
    点击上方“C语言与CPP编程”,选择“关注/置顶/星标公众号”干货福利,第一时间送达!传统的SystemCallI/O在Linux系统中,传统的访问方式是通过write()和read()两个系统调用实现的,通过read()函数读取文件到到缓存区中,然后通过write()方法把缓存中的数据输出到网络端口。......
  • 22 对话陈华良(下)|成长快的那些人,都有什么特性?
    你好,我是辰洋,《郭东白的架构课》的项目负责人。上节课东白老师与华良老师就职业规划、职业选择模型等问题,互相交流了看法与意见。那么我们这节课继续,看他们还聊了些什么。主持人:郭东白瓜子二手车集团CTO嘉宾:陈华良每日优鲜技术VP,前美团算法委员会主席完整的对话视频如下:......
  • TPT19新特性之形式化需求:自动生成测试用例
     在测试形式化需求的主题上,我们又向前迈进了一步。 如今,已经可以使用TPT自动评估形式化需求。在TPT19中,相应的测试数据现在可以一键生成。 这还在测试中吗?是的,但是完全自动并且不需要创建复杂的测试用例。 这适用于哪种测试对象呢? 适用于可以使用TPT测试的所......
  • matlab编写,计及碳捕集电厂低碳特性的含风电电力系统源-荷多时间尺度调度方法
    matlab编写,计及碳捕集电厂低碳特性的含风电电力系统源-荷多时间尺度调度方法关键词:碳捕集电厂,风电,电力系统,碳交易机制,需求响应,多时间尺度。ID:4695671994531492......
  • JDK1.8新特性(七):默认方法,真香,开动!接口?我要升级!!
    前期回顾:JDK1.8新特性(一):JDK1.8究竟有哪些新特性呢JDK1.8新特性(二):为什么要关注JDK1.8JDK1.8新特性(三):Lambda表达式,让你爱不释手JDK1.8新特性(四):函数式接口JDK1.8新特性(五):Stream,集合操作利器,让你好用到飞起来JDK1.8新特性(六):Stream的终极操作,轻松解决集合分组、汇总等复杂......
  • vue学习 第十一天 CSS3新特性 ---- 新增选择器(1、属性选择器 2、结构伪类选择
    CSS3新特性1、CSS3现状1)新增的CSS3特性有兼容性问题,ie9+才支持2)移动端支持优于PC端3.)不断改进中,应用相对广泛 2、CSS3新增选择器CSS3给我们新增了选择器,可以更加便捷,更加自由的选择目标元素。1)属性选......
  • vue学习 第十天(2) HTML5的新特性 ----- 语义化标签(布局标签)/ 多媒体标签(video、
    目标:能够说出3~5个HTML5新增布局和表单标签能够说出CSS3的新增特性有哪些 HTML5的新特性 HTML的新增特性主要是针对于以前的不足,增加了一些新的标签、新的表单和新的表单属性等。新特性都有兼容性问题,基本是IE9+以上版本......
  • Java SE 20 新增特性
    JavaSE20新增特性作者:Grey原文地址:博客园:JavaSE20新增特性CSDN:JavaSE20新增特性源码源仓库:Github:java_new_features镜像仓库:GitCode:java_new_featuresSwitch类型匹配(第四次预览)在JavaSE17新增特性中,Switch类型匹配作为预览功能推出,到JavaSE20,这个......