Java8 Lambda表达式入门

Lambda表达式的实质就是一个匿名函数。C#3.0引入了Lambda表达式,Java8也不甘示弱。Java8发布很久了,今天安装了JDK体验了Java8中的Lambda表达式。

首先看一个不适用Lambda表达式的例子。

比如我们要对一组字符串进行排序。

public class Hello {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Tan", "Zhen", "Yu");
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                return a.compareTo(b);
            }
        });
        for (String name : names) {
            System.out.println(name);
        }
    }
}

运行结果:

Tan
Yu
Zhen

同样的例子看一下使用Lambda表达式的代码:

public class Hello {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Tan", "Zhen", "Yu");
        Collections.sort(names, (String a, String b) -> a.compareTo(b));
        Stream<String> stream = names.stream();
        stream.forEach(System.out::println);
    }
}

是不是简洁很多。

下面详细介绍下Java8中的Lambda表达式。

(String a, String b) -> a.compareTo(b)就是一个Lambda表达式。前面括号中是函数的参数列表,->符号后面的是函数体。所以Lambda表示的写法是前面使用小括号列出函数参数,然后是用->符号指向函数体,函数体一般使用花括号{}括起来。

上面函数体a.compareTo(b)其实是一种简写。完整的写法应该是

(String a, String b) -> {
    returen a.compareTo(b);
}

因为函数体只有一句,一般可以省略大括号和return关键字。

Java中每一个Lambda表达式都对应一个类型,通常是接口类型,使用@FunctionalInterface进行注解。这种“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的Lambda表达式都会被匹配到这个抽象方法。即就是说每一个Lambda表达式对应函数式接口中的那个抽象方法。

此外,Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,。所以函数式接口中只能有一个抽象方法,其它的只能是扩展方法。下面是Java8中的Comparator接口,compare是抽象方法,此外还有一些扩展方法。

@FunctionalInterface
public interface Comparator {
    int compare(T o1, T o2);
    ......
}

在上面的示例代码中stream.forEach(System.out::println)一句的作用是使用Stream API输出每个字符串,下面进行详细解释。

Java 8引入了全新的Stream API。这里的Stream和I/O流不同,它更像具有Iterable的集合类,但行为和集合类又有所不同。Stream API引入的目的在于弥补Java函数式编程的缺陷。对于很多支持函数式编程的语言,map()、reduce()基本上都内置到语言的标准库中了(比如像Python和JavaScript这些语言)。

创建一个Stream有很多方法,最简单的方法是把一个Collection变成Stream,像上面的Stream<String> stream = names.stream()。

集合类新增的stream()方法用于把一个集合变成Stream,然后,通过filter()、map()等实现Stream的变换。Stream还有一个forEach()来完成每个元素的迭代。

这是forEach方法的签名void forEach(Consumer<? super T> action)。Consumer<? super T>也是一个函数式接口,所以我们应该传入一个函数。

Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,像上面的System.out::println是对println函数的引用。如果引用构造函数可以使用对象::new的形式。

个人感觉Java8中的函数式接口的作用和C#中的代理类型(delegate)比较像,或者说作用比较类似。

时间: 2024-10-13 15:58:55

Java8 Lambda表达式入门的相关文章

深入学习Java8 Lambda表达式 -- 从函数式接口说起

希望本文能够成为Java8 Lambda表达式的快速入门指南. 函数式接口 理解Functional Interface(函数式接口,以下简称FI)是学习Java8 Lambda表达式的关键所在,所以放在最开始讨论.FI的定义其实很简单:任何接口,如果只包含唯一一个抽象方法,那么它就是一个FI.为了让编译器帮助我们确保一个接口满足FI的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解.举个简单的例子,Runnable接口就是一个FI,下面是它的源

Java8 Lambda表达式深入学习(4) -- Java8实现方式

前几篇文章讨论了函数式接口和Lambda表达式语法.invokedynamic指令,以及Groovy2如何利用indy指令.本篇文章在前面几篇的基础之上,简要介绍Java8底层是如何实现Lambda表达式的. 示例代码 本文将以下面的代码为例展开讨论: import java.util.Arrays; import java.util.List; public class LambdaImplTest { public static void main(String[] args) { m1(A

java8 lambda表达式初接触

环境是jdk8 代码如下: package memTest; /** * Created by PC on 2014/8/5. */ public class LambdaOne { public static void test(){ new Thread(()-> System.out.print("hi") ).start(); } public static void main(String[] args) { new LambdaOne().test(); } } ja

Java8 Lambda表达式深入学习(2) -- InvokeDynamic指令详解

为了更好的支持动态类型语言,Java7通过JSR292给JVM增加了一条新的字节码指令:invokedynamic.之后,JVM上面的一些动态类型语言,比如Groovy(2.0+)和JRuby(1.7.0+)都开始支持invokedynamic.不过让人意外的是,为动态语言量身定制的invokedynamic指令,居然也被用到了Java8的Lambda表达式(JSR335)实现上.本文会对invokedynamic(以下简写做indy)指令做出详细解释. 测试代码 Java7以及更早版本的Jav

Java8 Lambda表达式应用案例 -- 单线程游戏服务器+异步数据库操作

前段时间我们游戏服务器的开发环境升级到了Java8,这两天我又把服务器的线程模型重新设计了一下,用上了Lambda表达式.Lambda表达式确实能够大幅简化Java代码,特别是丑陋不堪的匿名内部类,这篇文章主要就是想和大家分享这一点. 线程模型 首先简单介绍一下我们游戏服务器的线程模型,大致如下图所示: Netty线程池只处理消息的收发,当Netty收到消息之后,会交给游戏逻辑线程处理.由于是单线程在处理游戏逻辑,所以每一个消息必须很快处理完,也就是说,不能有数据库等耗时操作,不然逻辑线程很可能

Java8 Lambda表达式详解手册及实例

先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下Java8的新特性.Lambda表达式已经在新框架中普通使用了,如果你对Lambda还一无所知,真得认真学习一下本篇文章了. 现在进入正题Java8的Lambda,首先看一下发音 ([?l?md?])表达式.注意该词的发音,b是不发音的,da发[d?]音. 为什么要引入Lambda表达式 简单的来说,引入La

java8之lambda表达式入门

1.基本介绍 lambda表达式,即带有参数的表达式,为了更清晰地理解lambda表达式,先上代码: 1.1 两种方式的对比 1.1.1 方式1-匿名内部类 class Student{ private String name; private Double score; public Student(String name, Double score) { this.name = name; this.score = score; } public String getName() { ret

Java8 Lambda表达式介绍

欢迎进入我的博客:blog.scarlettbai.com查看更多文章 Lambda表达式是Java8里的一个重要特性,发布这么久了,最近在学swift语言时发现了其中的闭包的概念其实跟Lambda表达式极其相似,于是今天整理一下Java8中的Lambda表达式,做个介绍. Lambda表达式其实就是提供Java编程中对于函数式编程的支持,在我们习惯了一切皆对象时,刚接触Lambda可能读起来比较费劲,但是习惯之后,其确实有助于代码的简洁,且在Python.swift等中都有类似于Lambda这

java8 lambda表达式-语法

什么事lambda表达式,在百科的解释是 "Lambda 表达式"(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数.Lambda表达式可以表示闭包(注意和数学传统意义上的不同). 在java中我理解是匿名类,或者参数表达式(带有参数的可执行的代码块). (Type1 param1, Type2 param2, ..., TypeN