欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

程序员文章站 2022-04-05 08:57:48
...

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

前几天阿粉还在和同事抱怨,说现在 JDK 都已经11,12了,结果自己还在用 JDK 7,于是就发生了下面一幕。

阿粉:老宫阿(宫保鸡丁),你说现在 JDK 都已经出到11了,你说对咱们是不是太不友好了,我都快学不动了。

老宫:先别说出到几了,你们现在开发用的是啥?

阿粉:我们还是用的7呀!

老宫:你竟然还在用7,那你知道什么是 Lambda 么?

阿粉:Lambda?听过,但是没用过呀,但是据说挺好用的,但是我觉得学起来好麻烦,我想静静!

老宫:你是不知道呀,JDK8 里面可不仅仅是 Lambda,还有好多新特性呢!

于是故事开始了,在老宫(宫保鸡丁)的讲述下,阿粉也不得不重视起来了,阿粉也要开始学习 JDK8 了,不然再往后,都直接被淘汰了!

1. Java8 核心新特性讲解

Java 8的核心新特性:Lambda(匿名函数)、流、默认方法。

自1998年JDK 1.0(Java 1.0)发布以来,Java已经受到了学生、项目经理和程序员等一大 批活跃用户的欢迎。你看从学生,到项目经理,到程序员,这么多的角色都对 Java 情有独钟,看来不学是真的不行了。

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

Java 8对硬件也有影响:平常我们用的 CPU 都是多核的——你的笔记本电脑或台式机上的处理器可能有四个 CPU 内核,甚至更多。但是,绝大多数现有的 Java 程序都只使用其中一个内核,其他三个都闲着,或只是用一小部分的处理能力来运行操作系统或杀毒程序。在Java 8之前,专家们可能会告诉你,必须利用线程才能使用多个内核。问题是,线程用 起来很难,也容易出现错误。

从 Java 的演变路径来看,它一直致力于让并发编程更容易、 出错更少。Java 1.0里有线程和锁,甚至有一个内存模型——这是当时的最佳做法,但事实证明,不具备专门知识的项目团队很难可靠地使用这些基本模型。Java 5添加了工业级 的构建模块,如线程池和并发集合。Java 7添加了分支/合并(fork/join)框架,使得并行 变得更实用,但仍然很困难。

而Java 8对并行有了一个更简单的新思路,不过你仍要遵循一些规则,这些规则阿粉会在后边给大家讲。

2. Lambda表达式

2.1 什么是Lambda表达式

阿粉在研究 Java 8的时候第一件事就是研究的 Lambda 表达式是怎么书写的。

Lambda表达式是带有参数变量的表达式,是一段可以传递的代码,可以被一次或多次执行,是一种精简的字面写法,其实就是把匿名内部类中“一定”要做的工作省略掉,然后由JVM通过推导把简化的表达式还原。

先给大家来个传统排序。

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

排序结果:

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

阿粉再来带大家来看看使用 Lambda 表达式的方式:

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

其实这是 Lambda 表达式的简单的使用,Lambda表达式里面还有很多应用。比如说使用 Lambda表达式来实现多线程。

public class TestClass {
    public static void main(String[] args) {
        new Thread(()-> {
            for(int i=0;i<20;i++) {
                System.out.println("阿粉最帅");
            }
        }).start();
    }
}

其实你看到上面的 Lambda表达式 是不是感觉很简单,但是简单是简单,阿粉要问大家一个问题了?大家什么时候才适合使用 Lambda表达式呢?

2.2 什么时候使用 Lambda表达式

  • 需要显示创建函数式接口对象的地方,都可以使用

  • 实际上函数式接口的转换是Lambda表达式唯一能做的事情

  • 用于替换以前广泛使用的内部匿名类,各种回调

3. 使用函数式接口

函数式接口定义且只定义了一个抽象方法。函数式接口很有用,因为抽象方法的签名可以描述Lambda表达式的签名。函数式接口的抽象方法的签名 称为函数描述符。所以为了应用不同的Lambda表达式,你需要一套能够描述常见函数描 述符的函数式接口。Java API中已经有了几个函数式接口,比如说 Comparable、Runnable和Callable。

Predicate

@FunctionalInterface
public interface Predicate {
    boolean test(T t);
}

 public static  List filter(List list, Predicate p) {
        List results = new ArrayList<>();
        for (T s : list) {
            if (p.test(s)) {
                results.add(s);
            }
        }
        return results;
    }

Predicate nonEmptyStringPredicate = (String s) -> !s.isEmpty();

List nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);

java.util.function.Predicate接口定义了一个名叫test的抽象方法,它接受泛 型T对象,并返回一个boolean。现在就可以直接使用了。在我们需要表示一个涉及类型T的布尔表达式时,就可以使用这个接口。

Consumer

public static  void forEach(List list, Consumer c) {
        for (T i : list) {
            c.accept(i);
        }
    }

    forEach(Arrays.asList(1,2,3,4,5), (
    Integer i)->System.out.println(i) ←─Lambda是Consumer中accept方法的实现 );

java.util.function.Consumer定义了一个名叫accept的抽象方法,它接受泛型T 的对象,没有返回(void)。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用这个接口。比如,你可以用它来创建一个forEach方法,接受一个Integers的列 表,并对其中每个元素执行操作。在上面的代码中,你就可以使用这个forEach方法,并配合Lambda来打印列表中的所有元素。

至于剩下的 Function 阿粉就不给大家说了。

Java 8中的常用的函数式接口

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!

今天阿粉就先给大家说这些关于 Java8 的特性,阿粉在接下来的文章中会继续讲述 Java8 的新特性呦。

精彩回顾:

记一次线上 OOM 和性能优化

MyBatis 的 DAO 接口跟 XML 文件里面的 SQL 是如何建立关系的?

Gateway:数据报文走出局域网的必经之路

一文带你了解 Redis 的发布与订阅的底层原理