蔡不菜和他的uU们

  • 首页
  • 新鲜出炉
  • 我的记录
  • 我的动态
  • 我和uU
  • 好用分享
  • 关于与留言
志合者,不以山海为远;道乖者,不以咫尺为近
  1. 首页
  2. 学习,学习
  3. 正文

Lambda表达式与函数式接口

2021年12月1日 522人阅读 0人点赞 0条评论

lambda

简单记录一下学习的内容,不是很深入

基础语法

左侧:lambda 表达式的参数列表
右侧:lambda 表达式中所需要执行的功能,即lambda体

语法格式一:接口中的抽象方法,无参数,无返回值

()->System.out.println("hello lambda")

语法格式二:一个参数,并且无返回值

(x) -> System.out.println(x)

语法格式三:若只有一个参数,小括号可以不写

x -> System.out.println(x)

语法格式四:有两个以上的参数,有返回值,并且lambda体中有多条语句

Comparator<Integer> com = (x,y)->{
        System.out.println("函数式接口");
        return Integer.compare(x,y);
};

语法格式五:若lambda体中只有一条语句有参数,和返回值,大括号可以省略,return也可以省略
Comparator<Integer> com = (x,y)->Integer.compare(x,y);

语法格式六:lambda表达式的参数列表的参数类型可以省略不写,因为jvm可以根据上下文推断出数据类型
(Integer.x,Integer.y) -> Integer.compare(x,y)

巧记总结

左右遇一括号省
左侧推断类型省
能省就省

函数式接口

lambda表达式需要“函数式接口”的支持
接口中只有一个抽象方法的接口,称为函数式接口。可以使用@FunctionalInterface注解(方便编译器检查识别)

default和static方法均不是抽象方法

Java 8 四大核心函数式接口

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); };
    }
}

void accept(),实现该方法进行消费,消费的内容由传入的泛型决定

andThen(),个人理解为可以进行连续消费,当前这次消费逻辑accept()完成后,然后再进行下一次消费逻辑after.accept()

// 消费
public void test04(){
        Consumer<Double> consumer = money ->{
            money -= 100;
            System.out.println("您当前余额为"+money);
        };

        consumer.accept(1000.0);
    }

Supplier 接口

@FunctionalInterface
public interface Supplier<T> {
    T get();
}

T get(),实现该方法得到一个对象数据

// 需求:得到一个随机数数组
public void test03(){
        Supplier<Integer> supplier = () -> (int)(Math.random()*100);

        List<Integer> ret = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            ret.add(supplier.get());
        }

        // 遍历输出测试
    }

Function<T,R>:函数型接口,T为参数,R为返回值

@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;
    }
}

函数式接口,个人理解就是从一个值映射到另一个值,这两个值的类型没有要求,从Integer-->Intger或者Integer --> Object 都可以

R apply(T t) 实现该方法,方法内部就是你要完成的映射逻辑

compose() 先执行传入的before.apply(),再执行当前的apply(before.apply())

andThen() 和之前的函数式接口方法中的andThen()类似,就是接下来怎么做,先执行当前的映射然后怎么做,可以继续映射(执行传入的逻辑)

andThen()和compose() 区别:

andThen:先执行当前函数接口实现的apply逻辑,再执行传入的after.apply()逻辑

compose:先执行传入的before.apply()逻辑,再执行当前函数接口实现的apply()逻辑

//需求:处理字符串 也就是将原来的值映射为另一个值

    public void test02(){
        Function<String,String> process = str -> str.toLowerCase();
        String abde = process.apply("ABDE");

        Function<String,String> process2 = str -> str.trim();
        String apply = process2.apply("       abcd e   ");
    }

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);
    }
    static <T> Predicate<T> not(Predicate<? super T> target) {
        Objects.requireNonNull(target);
        return (Predicate<T>)target.negate();
    }
}

Predicate接口与Function接口很像,只不过其是将当前传入的参数映射(按照实现的逻辑)到true或者false

and() 将传入的数据与处理逻辑中用到的某个 参数进行 and 返回true 或false

or()

negate()

也就是 & | !

isEqual() 判断是否相等

同样这些操作可以连续执行,先and() 再 negate() ....

//需求:将满足条件的字符串,装入集合中

    public List<String> filterStr(List<String> list,Predicate<String> predict){
        List<String> ret = new ArrayList<>();

        for (String s : list) {
            if(predict.test(s)){
                ret.add(s);
            }
        }
        return ret;
    }

    public void test01(){
        List<String> list = Arrays.asList("hello","atguigu","lambda","www","ok");
        filterStr(list,str->str.length()>3);

        // 遍历输出 产看结果
        list.forEach(str - System.out.println(str))

    }

这些函数式接口大多数都可以进行链式执行(函数式编程),先这样,再这样,再这样....

下一篇内容关于 lambda应用— Stream

标签: JavaSE lambda
最后更新:2022年2月12日

Csy

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

取消回复
文章目录
  • lambda
    • 基础语法
    • 巧记总结
  • 函数式接口
    • Consumer接口
    • Supplier 接口
    • Function<T,R>:函数型接口,T为参数,R为返回值
    • andThen()和compose() 区别:
    • Predicate : 断言型接口

COPYRIGHT © 2021 caibucai.top. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

豫ICP备2021018055号