Java函数式编程一之基础介绍

简介

在Java8之前面对大型数据集合,Java 还欠缺高效的并行操作,为了编写这类处理批量数据的并行类库,同时也是为了更好的支持函数式编程,在语言层面上修改了现有的 Java:增加 Lambda 表达式。

Lambda

Lambda表达式能够简化原来冗杂的样板代码,如

button.setOnClickListener(new View.OnClickListener() {
	    @Override
	    public void onClick(View v) {
	        System.out.println("button clicked");
	    }
});
//以上代码可以简化为如下代码
button.setOnClickListener(v -> System.out.println("button clicked"));

Lambda表达式的形式

Lambda表达式有以下几种形式:

     //1、无参形式 
     Runnable runnable = () ->  System.out.println("无参数");
     //2、一个参数形式
     View.OnClickListener listener = v -> System.out.println("一个参数");
     View.OnClickListener listener = v -> {
	      System.out.println("一个参数");
	      System.out.println("一个参数");//多个语句可以使用代码块
	};
     //3、两个参数或多个形式
      BinaryOperator<Long> add = (x, y) -> x + y;
      BinaryOperator<Long> add = (Long x, Long y) -> x + y;//也可以显式的指定类型

有一点值得注意,Lambda表达式赋值的变量如上面的add表示的不是x + y的结果,而是x + y本身这个表达式。

函数式接口

Lambda 表达式的类型:函数接口(Function Interface)。函数接口就是只有一个抽象方法的接口(由@FunctionalInterface注解标识)!
图中绿色表示主要引入的新接口,其他接口基本上都是为了支持基本类型而添加的接口。
在这里插入图片描述

与面向对象主要抽象数据不同,函数式编程主要是为了抽象行为。函数式编程的核心是:在思考问题时,使用不可变值和函数,函数对一个值进行处理,映射成另一个值!

函数式接口的分类

JAVA 8提供了java.util.function包用于支持函数式编程,Function Interface主要分为以下四大类:Function、Predicate、Supplier、Consumer

一、功能性接口:Function

/**
 * Represents a function that accepts one argument and produces a result.
 * 功能性接口的接口定义为R apply(T t),它接收一个功能参数t,并返回一个功能结果R
 * @since 1.8
 */
@FunctionalInterface
public interface Function<T, R> {

    /**
     * Applies this function to the given argument.
     *
     * @param t the function argument
     * @return the function result
     */
    R apply(T t);
    ...
    }

二、断言性接口:Predicate

/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     * 断言接口主要应用于判断场景,其抽象接口为boolean test(T t)  类似返回值为Boolean的功能性接口
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
    ...
    }

三、供给性接口:Supplier

/**
 * Represents a supplier of results.
 * 供应接口的定义为T get(),不接收任何参数,有返回值
 * <p>There is no requirement that a new or distinct result be returned each
 * time the supplier is invoked.
 * 不要求每次调用供应接口都必须返回一个新的或者特别的结果
 * @param <T> the type of results supplied by this supplier
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     * @return a result
     */
    T get();
}

四、消费性接口:Consumer

/**
 * Represents an operation that accepts a single input argument and returns no
 * result. Unlike most other functional interfaces, {@code Consumer} is expected
 * to operate via side-effects.
 * 消费性接口的定义为void accept(T t),接收一个参数t,没有返回值。
 * 和大多功能性接口不同,Consumer接口期望执行带有副作用的操作
 *(意思是操作可能会更改输入参数的内部状态)
 * @param <T> the type of the input to the operation
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);
    ...
    }

示例

public class FunctionClassify {
    /**
     * 功能性接口:Function
     * 功能性接口的接口定义为R apply(T t),它接收一个功能参数t,并返回一个功能结果R
     */
    private static void test1() {
        Function<String, Object> function = (String str) -> str.length() > 3;
        System.out.println("function--" + function.apply("java"));

        Function<Integer, Object> function2 = a -> a + 10;
        System.out.println("function--" + function2.apply(3));

        Function<String, Integer> function3 = s -> s.length();
        System.out.println("function--" + function3.apply("java"));
    }

    /**
     * 断言性接口:Predicate
     * 断言接口主要应用于判断场景,其抽象接口为boolean test(T t)
     */
    private static void test2() {
        Predicate<String> predicate = str -> str.length() > 3;
        System.out.println("predicate--" + predicate.test("java"));

        Predicate<Integer> predicate2 = a -> true;
        System.out.println("predicate--" + predicate2.test(5));

        Predicate<String> predicate3 = s -> s.equalsIgnoreCase("Java");
        System.out.println("predicate--" + predicate3.test("java"));
        System.out.println("predicate--" + predicate3.test("javac"));
    }

    /**
     * 供给性接口:Supplier
     * 供应接口的定义为T get(),不接收任何参数,有返回值
     */
    private static void test3() {
        Supplier<String> supplier = () -> "Java".toLowerCase();
        System.out.println("supplier--" + supplier.get());
    }

    /**
     * 消费性接口:Consumer
     * 消费性接口的定义为void accept(T t),接收一个参数t,没有返回值。
     */
    private static void test4() {
        Consumer<String> consumer = s -> {
            System.out.println(  "consumer--" + s.toUpperCase());
        };
        consumer.accept("Java");
    }
    
    public static void main(String[] args) {
        test1();
        test2();
        test3();
        test4();
    }

}
//输出结果
function--true
function--13
function--4
predicate--true
predicate--true
predicate--true
predicate--false
supplier--java
consumer--JAVA

自定义函数式接口

public class Test2 {
   public static void main(String[] args) {
        String msg = "Hello World";
        CustomAction tCustomAction = System.out::println;
        test(tCustomAction, msg);
    }
    static void test(CustomAction action, String str) {
	   /**
	     * 和前面几种内置函数接口一样,使用“函数式接口.方法”的形式实现某种行为
	     * @param action
	     * @param str
	     */
       	 action.execute(str);
    }
}

@FunctionalInterface
interface CustomAction<T>{
    public void execute(T t);
}

Java函数式编程二

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值