热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JDK8新特性详细介绍[java入门]

本文由java零基础入门栏目为大家介绍JDK8中的一些新特性,欢迎大家来纠错指正!JDK8中的新特性主要有:1、函数式编程;2、Lambda表达式;3、函数式接口;4、方法引用;5

函数式编程

面向对象强调“一切皆对象”,如果想要做事情,必须要找到对象来做。函数式编程思想强调“做什么”,而不是“怎么做”。

普通的开启线程

// 匿名内部类对象
Runnable task = new Runnable() {
    @Override
    public void run() {
        System.out.println("乌鸦坐飞机");
    }
};
new Thread(task).start();

更多java相关免费视频教程:java在线教程

函数式编程开启线程

new Thread(() -> System.out.println("龙卷风摧毁停车场")).start();

前面的小括号:方法参数,没有参数时就写(),箭头指向后面要做的事情,箭头后面就好比是方法体大括号,代表具体要做的内容。

Lambda表达式

Lambda表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。

三要素:参数、箭头 、代码

格式:(参数类型 参数名称) -> { 一些代码 }

使用Lambda表达式的前提:必须要有接口并且接口中有且只有一个抽象方法

演示:编写一个Cook接口,接口中有一个makeFood()方法

public static void main(String[] args) {
    method(() -> {
        System.out.println("闪刀启动!");
    });
}
 
private static void method(Cook cook) {
    cook.makeFood();
}

Lambda表达式省略规则:

参数类型可以省略。但是只能同时省略所有参数的类型,或者干脆都不省略如果参数有且仅有一个,那么小括号可以省略如果大括号内的语句有且仅有一个,那么无论有没有返回值,return、大括号、分号都可以省略。

    public static void main(String[] args) {
        method((a, b)-> a + b);
    }
 
    private static void method(Calculator calculator) {
        int result = calculator.sum(1234, 9876);
        System.out.println(result);
    }

在new一个接口时,也可以使用lambda表达式来代替匿名内部类

Runnable task = () -> System.out.println("闪刀启动!");
new Thread(task).start();

函数式接口

接口当中有且仅有一个抽象方法,叫做函数式接口。

JDK8中新增了注解@FunctionalInterface,用于检测一个接口是否为函数式接口。如果不是函数式接口,编译时会报错。@FunctionalInerface注解是可选的,就算不用这个注解,只要保证接口满足函数式接口的定义要求,也一样是函数式接口。

@FunctionalInterface
public interface MyInterface {
    void method();
}

方法引用

Printer printer = (str) -> System.out.println(str);这段代码实际上可以简写。

只要是可推导的,就是可引用的,因此传参其实并没有意义,因此这里其实可以使用方法引用来简写 System.out::println

从java8开始,引入了一个全新的运算符,方法引用符(两个冒号连着写),所在的表达式就是一个方法引用,方法引用和Lambda本质是完全一样的,目的就是简化Lambda表达式的写法。

Lambda的写法:s->System.out.println(s)

方法引用写法:System.out::println

两种写发完全等效

 
    public static void main(String[] args) {
        method(System.out::println);
    }
 
    private static void method(Printer printer) {
        printer.print("hello");
    }

接口

default方法

接口本来是两个抽象方法,现在需要变成三个抽象方法,这个时候它的实现类也需要实现新的方法。

当实现类太多时,操作起来很麻烦,JDK之前是使用开闭设计模式:对扩展开放,对修改关闭。即:创建一个新的接口,继承原有的接口,定义新的方法,但是这样的话,原本的那些实现类并没有新的方法,这时候可以使用接口默认方法。

关键字使用default进行修饰, 方法需要方法体。这样的方法所有的子类会默认实现(不用自己写),如果想要覆盖重写,也可以在实现类中覆盖重写

/**
 * 从java8开始,接口当中允许定义default默认方法
 * 修饰符:public default(public可以省略,default不能省略)
 */
public interface MyInterface {
 
    void method1();
 
    void method2();
 
    default void methodNew() {
        System.out.println("接口默认方法执行");
    }
 
}

注意:接口中的default方法相当于是一个新的关键字,和四种修饰符的“default”并非一个概念。

活用default关键字,可以使程序达到“多继承”的效果。

static方法

从java8开始,接口当中允许定义静态方法,用法与一般类的静态方法相同。

public interface Animal {
 
    void eat();
 
    static Animal getAnimal() {
        return new Cat();
    }
}

流式操作

流式处理给开发者的第一感觉就是让集合操作变得简洁了许多,通常我们需要多行代码才能完成的操作,借助于流式处理可以在一行中实现。

比如我们希望对一个包含整数的集合中筛选出所有的偶数,并将其封装成为一个新的List返回,那么在java8之前,我们需要通过如下代码实现:

对于一个nums的集合:

List evens = new ArrayList<>();
for (final Integer num : nums) {
    if (num % 2 == 0) {
        evens.add(num);
    }
}

通过java8的流式处理,我们可以将代码简化为:

List evens = nums.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());

先简单解释一下上面这行语句的含义,stream()操作将集合转换成一个流,filter()执行我们自定义的筛选处理,这里是通过lambda表达式筛选出所有偶数,最后我们通过collect()对结果进行封装处理,并通过Collectors.toList()指定其封装成为一个List集合返回。

常用操作案例:

        //初始化list集合
        List list = new ArrayList();
        list.add("测试数据1");
        list.add("测试数据2");
        list.add("测试数据3");
        list.add("测试数据12");
        
        //使用λ表达式遍历集合
        list.forEach(s -> System.out.println(s));
        
        //结合Predicate使用和过滤条件筛选元素
        Predicate contain1 = n -> n.contains("1");
        Predicate contain2 = n -> n.contains("2");
        
        //根据条件遍历集合
        list.stream().filter(contain1).forEach(n -> System.out.println(n));
        list.stream().filter(s -> contain1.test(s)).forEach(s -> System.out.println(s));
        list.stream().filter(contain1.and(contain2)).forEach(n -> System.out.println(n));
        list.stream().filter(contain1.or(contain2)).forEach(n -> System.out.println(n));
        
        //将过滤后的元素重新放到一个集合中
        List newList = list.stream().filter(contain1.and(contain2)).collect(Collectors.toList());
        
集合中decimal求和
		BigDecimal sum = list
				.stream()
				.map(Person::getAmount)
				.reduce(BigDecimal::add)
				.get();
 
//排序 , 也需要新的集合接收
	List resultList = new ArrayList();
	resultList = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList())

推荐java相关文章:java零基础入门

欢迎大家一起来学习!


推荐阅读
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
author-avatar
vivianchen1988
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有