Java8 函数式编程

本文介绍了Java 8中的函数式编程概念,包括Predicate、Function、Consumer、Supplier、UnaryOperator和BinaryOperator等接口的使用,强调了lambda表达式和接口默认实现如何简化编程。通过示例展示了如何进行函数链式编程和方法引用,帮助理解如何在实际业务中应用这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java 8 函数式编程用法

概览

jdk 8中新增了lambda和接口默认实现方式,简化了编程,让我们可以转换为新的函数式编程,更多关注于业务逻辑.
对于提供的所有function功能在package java.util.function下可以找到,这里列举其中一些常用用法

@FunctionalInterface 编译时期检验了接口只有唯一方法合法性,可以有多个默认实现方法

@FunctionalInterface
interface INumberFunction{
    int doubleNum(int num);
    default void printNum(int num){
        System.out.println("print info:"+num);
    }
}

测试代码:

INumberFunction numberFunction= x->x*2;
System.out.println(numberFunction.doubleNum(20));
//---------------output
//40

当接口继承多个接口时,有相同默认实现方法时会编译期指示要求override实现采用哪个接口的默认方法实现

@FunctionalInterface
interface INumberFunction2{
    int doubleNum(int num);
    default void printNum(int num){
        System.out.println("print info2:"+num);
    }
}

@FunctionalInterface
interface INumberFunction3 extends INumberFunction,INumberFunction2{
    //必须要覆写继承的多个接口中相同的默认实现方法
    @Override
    default void printNum(int num) {
        INumberFunction2.super.printNum(num);
    }
}

Predicate

断言,输入为T类型的数据,输出boolean

T->boolean(true/false)

Predicate<String> predicate=x->x.startsWith("Class");
System.out.println(predicate.test("Abcd"));
//----------------output
//false

对基本数据类型的包装了IntPredicate

BiPredicate<T,U>

二元断言,输入T类型和U类型的数据,返回boolean

(T, U) -> boolean(true/false)

BiPredicate<String,Double> biPredicate=(x,y)->x.startsWith("Alisa")&&y.intValue()>=8000;
System.out.println("Alisa salary is over average:"+biPredicate.test("Alisa",8100.02));
//----------------output
//Alisa salary is over average:true

Function<T,S>

T 代表输入类型,S代表函数执行完返回结果类型

T->S

case 1:

Function<Integer,String> formatFunc=x->new DecimalFormat("#,###").format(x);
System.out.println("format result:"+formatFunc.apply(10000));
//----------------output
//format result:10,000

case 2:

函数链式编程

Function<Integer,Integer> func = x->x*2;
System.out.println(func.andThen(x->"result:"+x).apply(20));
//--------------output
//result:40

case 3:

多个链式时,从左到右顺序执行

Function<String,Integer> func = x->Integer.valueOf(x);
System.out.println(func.andThen(/*y is Integer*/y->Double.valueOf(y)).apply("1000"));
//-----------------output
//1000.0

System.out.println(func.andThen(y->y+200).andThen(z->Double.valueOf(z)).apply("1000"));
//---------------------output
//1200.0

System.out.println(func.andThen(/*y is Integer*/y->Long.valueOf(y+100+"")/*return Long to next andThen or as final result*/)
        .andThen(/*z is Long*/z->Double.valueOf(z)/*return Double to next andThen or as final result*/).apply("1000"));
//---------------------output
//1100.0

对于有参构造函数时,Function接口也适用

Function<String,String> strFunc=String::new;
System.out.println("construct str:"+strFunc.apply("Message"));
//---------------------output
//Message

对于输入数据为一些基本类型的情况,有封装了对应的Function如IntFunction,DoubleFunction…

对于输入和输出的数据都为一些基本类型的情况,封装了有DoubleToIntFunction,IntToLongFunction…

BiFunction<T, U, R>

二元功能函数,输入T类型和U类型的实例,返回R类型的实例

(T, U) -> R

BiFunction<Integer,Double,String> biFunction=(x,y)->"string value:"+x.intValue()+y.intValue();
System.out.println(biFunction.apply(100,200.01));
//-----------------output
//string value:100200

对返回结果为一些基本类型的封装了更简洁的BiFunction,如ToDoubleBiFunction<T,U> 返回double类型的结果,ToLongBiFunction

如果入参和返回结果的类型都与方法引用匹配时,可以直接用方法引用,参考Consumer.

Consumer

输入T类型的实例,没有返回,只是消费输入

case 1:

Consumer<String> consumer = x -> System.out.println("if contains AI:" + x.contains("AI"));
consumer.accept("AI message");
//---------------------output
//if contains AI:true

如果输入与调用的方法参数类型一致,可以直接用方法引用,如下

case 2:

简单方法引用

Consumer<String> consumer1 = System.out::println;
consumer1.accept("New message");
//---------------------output
//New message

case 3:

静态方法引用

public class FunctionMain {

    public static void main(String[] args) {
      Consumer<Double> consumer2= FunctionMain::floorDouble;
      consumer2.accept(234.5);
    }
    public static void floorDouble(Double num){
        double floor = Math.floor(num);
        System.out.println("floor double:"+floor);
    }
 }
//---------------------output
//floor double:234.0

case 4:

非静态方法引用

public class FunctionMain {
    public static void main(String[] args) {
       FunctionMain functionMain=new FunctionMain();
       Consumer<Date> dateConsumer=functionMain::formatDate;
       dateConsumer.accept(new Date());
        //另外一种情况,采用方法隐式this对象的性质一样可以使用类方法调用,但调用时需要传入实例对象
        BiConsumer<FunctionMain,Date> dateBiConsumer =FunctionMain::formatDate;
        dateBiConsumer.accept(functionMain,new Date());
    }
    
    //private void formatDate(FunctionMain this,Date date){
    //    String newDate = new SimpleDateFormat("yyyy.MM.dd").format(date);
    //    System.out.println("formatDate: "+newDate);
    //}
    private void formatDate(/*隐藏了this参数,与上述方法等价*/Date date){
        String newDate = new SimpleDateFormat("yyyy.MM.dd").format(date);
        System.out.println("formatDate: "+newDate);
    }
 }
//---------------------output
//formatDate: 2020.08.15

BiConsumer<T,U>

二元消费函数,输入T类型和U类型的实例,无输出

BiConsumer<String,Double> biConsumer=(x, y)-> System.out.println("weight result:"+Integer.valueOf(x)*3+y.intValue()*7);
biConsumer.accept("20",12.32);
//---------------------output
//weight result:6084

Supplier

没有输入,返回T类型的实例

Supplier<List<String>> supplier= ArrayList::new; //or Arrays::asList
System.out.println(supplier.get());
//---------------------output
//[]

基本类型封装了一些对应的Supplier,比如IntSupplier, LongSupplier, DoubleSupplier, BooleanSupplier

UnaryOperator

一元函数,输入为T类型的实例,输出也为T类型的实例

T->T

UnaryOperator<String> ua=x->x.concat(" end");
System.out.println(ua.apply("hello"));
//-------------------------output
//hello end

封装了基本类型的一元函数,IntUnaryOperator, DoubleUnaryOperator…

BinaryOperator

二元函数,输入类型为T的两个参数,输出类型为T的结果

(T, T)-> T

BinaryOperator<Boolean> bo=(x, y)->x&&y;
System.out.println(bo.apply(true,false));
//--------------------output
//false

IntBinaryOperator ibo = (x,y)->x*5+y*10;
System.out.println(ibo.applyAsInt(2,3));
//--------------------output
//40

*参数,输出类型为T的结果

(T, T)-> T

BinaryOperator<Boolean> bo=(x, y)->x&&y;
System.out.println(bo.apply(true,false));
//--------------------output
//false

IntBinaryOperator ibo = (x,y)->x*5+y*10;
System.out.println(ibo.applyAsInt(2,3));
//--------------------output
//40

对一些基本类型封装了对应的BinaryOperator, 如IntBinaryOperator, LongUnaryOperator

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值