`
liugang594
  • 浏览: 989714 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java函数式编程学习一

 
阅读更多

一、缺省方法

首先看一段用Java 8写的代码:

 

        //create a list, and add 3 elements
        List<String> l = new ArrayList<String>() {
            {
                add("Hello");
                add("World");
                add("Peace");
            }
        };
        //print element in l one by one
        l.forEach(System.out::println);

 

首先创建一个 List 对象,并添加了三个元素到其中,然后调用 List 的 forEach 方法将其中的元素一个一个打印出来。

但是我们都知道 List 是一个接口,其中没有 forEach 方法,而如果直接在 List 接口中添加新的方法定义,则会破坏向下兼容性,因为以前的程序在新的Java环境里因缺少对该方法的实现而报错。Java 8中解决这一问题的手段就是使用缺省方法。

 

缺省方法是在接口中定义方法实现的一种方式,并且保证所有已经存在的子类的兼容性,所以实现了接口的类默认都拥有在接口中定义的缺省方法,这有点像一个抽象类。当一个子类中没有覆盖缺省方法时,则对子类的该方法的调用将调用接口中的实现。缺省方法的声明方式如下:

 

public interface DefaultInterface {
    default int getValue(){
        return 1;
    }
}

只需要在方法前加关键字 default 即可。

 

缺省方法提供了一种在不破坏现在接口实现的情况下,给接口添加新的功能的途径。查看集合类的源码就会发现Java 8的集合类接口中添加了很多缺省的方法实现,用于提供对集合的共同的操作,如上所示的 forEach 方法。 

 

一个类可以实现多个接口,如果其中有多于一个接口有相同的缺省方法时,则子类需要定义自己的实现,否则会报编译错误:

interface A{
    default String name(){
        return "A";
    }
}
interface B{
    default String name(){
        return "B";
    }
}
class C implements A, B{
    public String name(){
        return A.super.name();
    }
}

 

二、forEach() 方法

forEach() 方法的源码如下:

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

这里 this 对象就是 List 对象本身,t 就是 List 中的遍历的元素。写在我们熟悉的方式就是:

        for(String s: l){
            action.accept(s);
        }

 

三、java.util.function.Consumer 接口

看上面 forEach() 方法参数,需要的是一个 Consumer 对象,这里我们传入的是一个 System.out::println 。 Consumer 是新增的函数编程接口中的一个,看它的介绍:

Represents an operation that accepts a single input argument and returns no result.

而双冒号 :: 操作符也是新增的一个操作符,表示一个函数引用。结合起来理解应该就是:一个类的任何一个方法,如果它只有一个参数,并且没有返回值,则在需要Consumer参数的地方都可以把此方法作为函数引用传入。

可以作个实验。先定义以下类:

class TestConsumer{
    public static TestConsumer INSTANCE = new TestConsumer();
    public void sayHello(String s){
        System.out.println("Hello "+s);
    }
}

然后替换 System.out::println 为 TestConsumer.INSTANCE::sayHello,如下:

        //create a list, and add 3 elements
        List<String> l = new ArrayList<String>() {
            {
                add("Hello");
                add("World");
                add("Peace");
            }
        };
        //print element in l one by one
        l.forEach(TestConsumer.INSTANCE::sayHello);

看打印结果:

Hello Hello
Hello World
Hello Peace

证明我们的猜想是对的。

再试一下静态方法,修改上面的TestConsumer类,添加一个静态方法:

    public static void greeting(String s){
        System.out.println("Greeting "+s);
    }

还是替换 forEach() 中的参数:

l.forEach(TestConsumer::greeting);

这次和普通的静态方法一样,直接通过类访问函数对象。打印结果:

Greeting Hello
Greeting World
Greeting Peace

由上证明,Consumer接口对于静态和实例方法都是适用的。     

 

另外,我们也可以实现一个方法,其他要求传入一个Consumer对象:

public class TestConsumer {
    
    public static void main(String[] args) {
        TestConsumer test = new TestConsumer();
        test.tryConsumer(System.out::println, "hello");
    }
    
    public void tryConsumer(Consumer c, String t){
        c.accept(t);
    }
    
}

仔细想来,这其实就有点类似于C/C++的传入方法指针之类的东西:Consumer可以根据传入的函数引用不用而执行不同的操作。  

 

 

 

分享到:
评论

相关推荐

    Java-Java函数式编程教程

    Java函数式编程是一种编程范式,它强调使用函数作为程序的基本构建块,将计算视为函数的组合,并且尽可能避免改变状态和可变数据。在Java 8及更高版本中,函数式编程得到了官方的大力支持,引入了Lambda表达式、...

    《Java函数式编程》_高清华.zip

    10. **学习资源**:要深入学习Java函数式编程,《Java函数式编程》_高清华这本书可能是很好的起点,它可能涵盖了Lambda表达式的使用、Stream API的实践以及如何在实际项目中应用函数式编程思维等内容。 通过理解和...

    黑马程序员Java函数式编程全套视频教程,Lambda表达式、Stream流、函数式编程一套全通关1

    本套黑马程序员的Java函数式编程视频教程涵盖了Lambda表达式、Stream流以及函数式编程的核心概念,旨在帮助学习者全面掌握这一现代编程技术。 Lambda表达式是Java 8引入的关键特性,它允许我们以更简洁的方式定义...

    java lambda函数式编程完成实例代码

    Java Lambda 函数式编程是Java 8引入的一项重要特性,它极大地简化了处理函数对象的方式,使得代码更加简洁、易读。Lambda表达式是函数式编程的核心,它允许我们将函数作为一个参数传递,或者将函数作为返回值。在这...

    读书笔记:java 函数式编程学习.zip

    读书笔记:java 函数式编程学习

    深入理解Java函数式编程和Streams API

    ### 深入理解Java函数式编程和Streams API #### 一、引言 随着Java 8的发布,函数式编程范式正式被引入到Java语言中,这标志着Java编程方式的重大转变。Java 8引入了Lambda表达式、方法引用等新特性,使得Java能够...

    Scala函数式编程

    函数式编程(FP)是一种软件开发风格,它注重不依赖于编程状态的函数。函数式代码易于测试和复用,容易实现并发,且不容易受到bug的攻击。Scala是一种能很好支持函数式编程的新兴JVM语言。《Scala函数式编程》是针对...

    javascript函数式编程

    对于已经熟悉Java的开发者来说,学习JavaScript函数式编程不仅可以拓宽视野,也有助于提升在前端开发领域的专业技能。阅读相关书籍,例如"javascript函数式编程",将帮助你更好地掌握这些概念并应用于实际项目中。

    Java 8函数式编程 范例

    Java 8是Java语言的一个重要版本,引入了大量新特性,其中最具革命性的就是函数式编程的支持。函数式编程在Java 8中的实现主要体现在Lambda表达式、Stream API以及方法引用等方面,这些新特性极大地提高了代码的简洁...

    基于Java 8的函数式编程学习项目.zip

    基于Java 8的函数式编程学习项目 项目概述 本项目是基于Java 8的函数式编程学习项目,主要涵盖了Java 8中引入的Stream API、Lambda表达式、函数式接口、Optional类、时间API等特性。通过多个示例文件,展示了如何...

    Java 8函数式编程1

    【Java 8函数式编程】 Java 8 是Java平台的一个重大更新,引入了多项新特性,其中最引人注目的就是对函数...对于已经熟悉Java SE的开发者来说,学习并应用Java 8的函数式编程特性,能够提升他们的编程效率和代码质量。

    Java8函数式编程1

    【Java 8 函数式编程】是针对Java开发者的一本技术书籍,旨在介绍Java 8引入的函数式编程概念和特性。作者Richard Warburton希望通过这本书挑战传统观念,即函数式编程只适合少数专业人士,而让更多的程序员能够理解...

    函数式编程另类指南.pdf

    **函数式编程**是一种编程范式,它将计算过程视为一系列函数调用。与传统的命令式编程不同,函数式编程强调不可变性和纯函数的概念,即函数的结果只依赖于输入参数,并且在执行过程中不会改变外部状态。 #### 二、...

    面向Java开发者的函数式编程

    《面向Java开发者的函数式编程》是由Dean Wampler编写的一本专业书籍,旨在为Java开发者介绍函数式编程(Functional Programming,简称FP)的基本原理及其在Java中的应用。本书以简明扼略的方式介绍了函数式编程的...

    Scala与Clojure函数式编程模式:Java虚拟机高效编程1

    这本书适合有编程基础,对函数式编程感兴趣的读者,无论你是Java开发者还是对新编程范式好奇的学习者,都可以从中了解到如何在Scala和Clojure中应用函数式编程来提高代码质量和效率。 【结论】 随着大数据时代的...

    java8函数式编程学习源码

    本资源"java8函数式编程学习源码"显然是为了帮助开发者深入理解并实践这些概念。下面我们将详细探讨其中的关键知识点。 1. **Lambda 表达式**: Lambda 表达式是 Java 8 中最具代表性的新特性,它提供了一种简洁的...

    函数式编程思想

    函数式编程是一种编程范式,它将计算视为数学函数的求值,并强调程序的数据流和变换,而不是对指令进行控制。在Java世界中,虽然它最初设计为命令式语言,但自Java 8以来,已经引入了丰富的函数式编程特性,使得...

    Java8 函数式编程1

    【Java 8 函数式编程】是针对Java开发者的一本技术书籍,主要讲解了Java 8引入的新特性,特别是函数式编程的概念及其应用。作者Richard Warburton旨在打破函数式编程仅限于少数人的认知,让更多的Java程序员能够理解...

    Java 8函数式编程学习笔记.zip

    Java 8是Java语言的一个重要版本,引入了大量新特性,其中最具革命性的就是函数式编程的支持。函数式编程是一种编程范式,它强调将计算视为函数的组合,避免可变状态和副作用,使得代码更加简洁、易于测试和并行化。...

Global site tag (gtag.js) - Google Analytics