java8函数式编程

本文详细介绍了Java8中的函数式编程概念,包括不可变性、Lambda表达式、四大内置函数式接口(Consumer、Supplier、Function、Predicate)以及递归和方法引用的使用。通过实例展示了如何在实际编程中应用这些特性,如使用Lambda简化代码,以及如何通过方法引用提高代码的可读性。

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

系列文章目录

第一章 万事万物皆对象
第二章 java构造器
第三章 java访问权限
第四章 java初始化
第五章 java继承
第六章 java重载与重写
第七章 java接口和抽象类
第八章 java数组
第九章 java内部类
第十章 java时间操作
第十一章 final关键字
第十二章 java字符串
第十三章 java异常
第十四章 java泛型
第十五章 java IO操作
第十六章 java NIO操作
第十七章 java zip压缩
第十八章 java反射
第十九章 java反射之Type接口
第二十章 java8流式操作
第二十一章 java8函数式编程



函数式编程

函数式编程强加了额外的约束,即所有数据必须是不可变的:设置一次,永不改变。将值传递给函数,该函数然后生成新值但从不修改自身外部的任何东西,不可变对象和无副作用范式解决了并发编程中最基本和最棘手的问题之一。

Lambda表达式只支持函数式接口,也就是只有一个抽象方法的接口

普通用法和函数式编程对比

@FunctionalInterface //用于判断是否符合函数式接口
public interface Interf {
    String f(String msg);
}

public class InterfImpl implements Interf {
    @Override
    public String f(String msg) {
        return msg + " 普通实现";
    }

    static String func(String msg) {
        return msg + " 方法引用";
    }

    public static void main(String[] args) {
        Interf[] interfs = new Interf[]{
                new InterfImpl(),//普通实现
                new Interf() {
                    @Override
                    public String f(String msg) {
                        return msg + " 匿名内部类";
                    }
                },//匿名内部类
                msg -> msg + " lambda", //lambda表达式
                InterfImpl::func //方法引用
        };

        for(Interf interf : interfs){
            System.out.println(interf.f("测试lambda"));
        }
    }
}

lambda表达式

lambda表达式,由箭头->分隔开参数和函数体,箭头左边是参数,右边是lambda返回的表达式,即函数体

lambda表达式就是函数式接口的实例

  • 当只有一个参数,可以不用括号()
  • 如果没有参数,必须使用()表示空参数列表
  • 对于多个参数,将参数列表放在括号()中
  • 如果有多行,需要将这些行放在花括号,在这种情况下,需要使用return

四个内置函数式接口

Consumer 消费型接口
@FunctionalInterface
public interface Consumer<T> {

    void accept(T t);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}
public static void testConsumer(){
  Consumer<Double> consumer = d -> System.out.println("花费"+d+"元");
  consumer.accept(1000d);
}
Supplier 供给型接口
@FunctionalInterface
public interface Supplier<T> {
    T get();
}
public static void testSupplier(){
  Supplier<Integer> supplier = () -> {
    return 100;
  };
  System.out.println(supplier.get());
}
Function 函数型接口
@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);
  
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}
public static void testFunction(){
  Function<Integer,Integer> function = x -> {
    return x*100;
  };
  System.out.println(function.apply(10));
}
Predicate 断言型接口
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}
public static void testPredicate(){
  Predicate<String> predicate = x -> {
    return "yes".equals(x);
  };
  System.out.println(predicate.test("no"));
}

递归

递归的Lambda表达式,递归方法必须是实例变量或静态变量

计算阶乘

@FunctionalInterface
public interface IntCall {
    int call(int i);
}

public class Recursion {
    private IntCall intCall;
    public static void main(String[] args) {
        Recursion recursion = new Recursion();
        recursion.intCall = n -> n == 0 ? 1 : n * recursion.intCall.call(n - 1);
        for (int i = 0; i < 10; i++)
            System.out.println(i+"! = "+recursion.intCall.call(i));
    }
}

方法引用

java8的方法引用,由::区分,在::左边是类或对象的名称,在::的右边是方法的名称,但是没有参数列表

如果lambda体的内容有方法已经实现了,可以使用方法引用

方法引用其实也是lambda表达式,要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的形参列表和返回值类型相同

三种语法格式
1、对象::实例方法
2、类::静态方法
3、类::实例方法 当lambda表达式第一个参数是实例方法的调用者,第二个参数是实例方法的参数时,可以使用

public class TestMethodRef {

    /**
     * 对象::实例方法
     */
    public static void test1(){
        Consumer<String> con =  System.out::println;
        con.accept("aaaa");

    }

    /**
     * 类::静态方法
     */
    public static void test2(){
        Consumer<String> con =  TestMethodRef::testStatic;
        con.accept("xxxx");
    }

    /**
     * 类::实例方法
     */
    public static void test3(){
        MyTest myTest = String::equals;
    }

    /**
     * 测试无参构造器
     * @return
     */
    public static TestMethodRef test4(){
        Supplier<TestMethodRef> supplier = TestMethodRef::new;
        return supplier.get();
    }

    /**
     * 测试有参构造器
     * @return
     */
    public static TestMethodRef test5(){
        Function<Integer,TestMethodRef> function = TestMethodRef::new;
        return function.apply(10);
    }

    public TestMethodRef(){
        System.out.println("无参构造器调用");
    }

    private int x;
    public TestMethodRef(int x){
        this.x = x;
    }



    public static void main(String[] args) {
        test1();
        test2();
        test3();
        test4();
        TestMethodRef t = test5();
        System.out.println(t.x);
    }

    public static void testStatic(String x){
        System.out.println("我输出入了"+x);
    }


}

@FunctionalInterface
interface MyTest{
    boolean test(String x,String y);
}

参考文献

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾光师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值