首页 > 其他分享 >Lambda表达式

Lambda表达式

时间:2023-04-25 16:12:44浏览次数:20  
标签:function Function return System println out 表达式 Lambda

1、Lambda表达式初步认识

java是一个面向对象的语言,而Lambda表达式却是一个匿名函数,因此java把Lambda表达式抽象成一个匿名内部类(jdk中没有抽象出来,但是它是一个匿名内部类的实现,在下面的截图中,很明显可以看到是一个内部类的地址

为了证实如上所说,我就随手写了一个lambda表达式,来调试一下。

package com.neo.web;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class Test2 {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("gjeiogj");
        list.add("ghreeh");
        list.add("ujjkk");
        List<Integer> length = list.stream().map(String::length).collect(Collectors.toList());
        System.out.println(length);
        List<String> collect = list.stream().filter(t -> t.length() > 6).collect(Collectors.toList());
        System.out.println(collect);


        // 消费者
        Consumer<Integer> c = t -> System.out.println(t.toString());
        c.accept(1111);


        // 生产者
        Supplier<String> s = () -> "qwe";
        System.out.println(s.get());

        // 断言类型
        Predicate<Integer> p = t -> {
            if (t > 0) {
                return true;
            }
            return false;
        };
        System.out.println(p.test(-1));



    }
}

在debug状态下,我们可以通过watch清楚的看到lambda表达式是一个内部类。清楚了这一点之后,我想对我们理解lambda表达式有着重要的帮助 

 

 

2、基本结构

Lambda表达式分为3块,分别是参数模块,->,代码块。类似下面的形式。

参数模块 代码块
//真正的表达应该是这样子的
(param1,param2,...,paramn) -> {code body }

分三块来说明一下

1)参数模块

参数模块顾名思义,就是代表着传入Lambda表达式的代码的参数。不需要传参数时,可以直接使用()即可,在参数只有1个的时候,()可以省略。同时也推荐省略。

 

2)代码模块

代码模块的具体作用就是处理逻辑的具体实现。 需要注意的是,在具体实现的时候,每个分之都必须满足其返回值,这也好比是函数,规定了返回值类型,如果某一个分之返回与之不合的返回值类型,那就肯定错了。

3、函数式接口

定义:只有一个抽象方法的接口。

定义十分简单,但是却有一些比较关键的字眼,我抽取其中三个词:一个,抽象,接口。

一个:只有一个抽象方法,多了不行,少了也不行。

函数式接口常见的Runnable等

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

函数式接口的抽象方法,与之对应的Lambda表达式的参数就是这个抽象方法的参数,返回值就是这个抽象方法的返回值。

例如:

@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);
}
Function接口的apply方法,入参类型是T,返回值类型是R
Function<String, Integer> f = item -> item.length();
Integer length = f.apply("bbbb");
System.out.println(length);

Lambda表达式的item是实参,类型是String,item.length()是返回值,且类型是Integer。

4、几种常用函数式接口

1、生产者Supplier

@FunctionalInterface
public interface Supplier<T> {

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

功能:不传递参数,返回一个值

生产者(可以理解为,不接受任何参数,返回一个值,究竟返回什么值由调用者决定----Lambda表达式的制造者)

Supplier<String> s = () -> "abc";
String s1 = s.get();
System.out.println(s1);

2、消费者Consumer

@FunctionalInterface
public interface Consumer<T> {

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

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

功能:传递一个参数,无返回

接收一个参数处理后,无返回值

Consumer<String> c = item -> System.out.println(item);
c.accept("hello");

3、Function (功能接口)

功能:传递1个参数,返回1个参数。

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

举例:

//输出字符串的长度
Function<String, Integer> f = item -> item.length();
Integer length = f.apply("bbbb");
System.out.println(length);

输入String类型的字符串,返回值是Integer类型的字符串长度。

在Function<T,R>函数式接口中还有着其他方法【compose】,【andThen】,【identity】,这三个方法其实可能也存在其他函数式接口中(在BiFunction这样的接口中,compose方法是不存在的),

对于这样的方法来说在每个函数接口中都是有着自己的实现,只不过我们在读取源码之后发现他在每个函数式接口中的实现都大致相似,因此在Function这个接口中进行一个分析,其他的接口中就不分析了。

1.compose方法,在javadoc中如下描述。 Returns a composed function that first applies the {@code before},其实很简单就是一个前置执行,需要注意的是它传入的是一个Function接口,返回的也是一个Function接口。

/**
     * Returns a composed function that first applies the {@code before}
     * function to its input, and then applies this function to the result.
     * If evaluation of either function throws an exception, it is relayed to
     * the caller of the composed function.
     *
     * @param <V> the type of input to the {@code before} function, and to the
     *           composed function
     * @param before the function to apply before this function is applied
     * @return a composed function that first applies the {@code before}
     * function and then applies this function
     * @throws NullPointerException if before is null
     *
     * @see #andThen(Function)
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

举例:

import java.util.function.Function;

public class FunctionTest {

    public static void main(String[] args) {

        //接受一个值,返回一个Boolean值
        Function<Integer, Integer> function1 = i -> {
            if (i > 2) {
                return 2;
            } else {
                return 3;
            }
        };

        Function<Integer, Integer> function2 = i -> i * i;

        //在function2执行之前,先执行function1,1小于2返回3,3*3 = 9
        Integer integer = function2.compose(function1).apply(1);
        System.out.println(integer);


        //在function1执行之前,先执行function2,猜测一下  1*1 = 1 ,比2小返回3
        Integer integer2 = function1.compose(function2).apply(1);
        System.out.println(integer2);
    }
}

2、andThen也非常好理解了,就是一个后置执行。

举例:

import java.util.function.Function;

public class FunctionTest {

    public static void main(String[] args) {

        //接受一个值,返回一个Boolean值
        Function<Integer, Integer> function1 = i -> {
            if (i > 2) {
                return 2;
            } else {
                return 3;
            }
        };

        Function<Integer, Integer> function2 = i -> i * i;

        //在function2执行后,再执行function1,1*1 = 1 ,比2小返回3
        Integer integer = function2.andThen(function1).apply(1);
        System.out.println(integer);


        //在function1执行后,再执行function2,1<2,返回3 ,3*3=9
        Integer integer2 = function1.andThen(function2).apply(1);
        System.out.println(integer2);
    }
}

3、identity这个静态方法根据javadoc中的描述,返回的是一个function,返回自己本身。

/**
     * Returns a function that always returns its input argument.
     *
     * @param <T> the type of the input and output objects to the function
     * @return a function that always returns its input argument
     */
    static <T> Function<T, T> identity() {
        return t -> t;
    }

举例:

将多个字符串组装成map,且key是自身,value为字符串长度

Stream<String> stream = Stream.of("hello", "world", "aaa", "c");
Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), item -> item.length()));

 

 

4、Predicate (断言接口)

功能: 传递一个参数,返回一个Boolean值。先看javadoc

@FunctionalInterface
public interface Predicate<T> {

    /**
     * Evaluates this predicate on the given argument.
     *
     * @param t the input argument
     * @return {@code true} if the input argument matches the predicate,
     * otherwise {@code false}
     */
    boolean test(T t);
}

举例:

        Predicate<Integer> predicate = integer -> {
            if (integer > 3){
                return true;
            } else {
                return false;
            }
        };
        System.out.println(predicate.test(2));

        Function<Integer,Boolean> function = integer -> {
            if (integer > 3){
                return true;
            } else {
                return false;
            }
        };
        System.out.println(function.apply(2));

 

标签:function,Function,return,System,println,out,表达式,Lambda
From: https://www.cnblogs.com/longan-wang/p/16882980.html

相关文章

  • java8 lambda 求list最大值、最小值、平均值、求和、中位数、属性排序(空指针异常,空值
    点击查看代码importorg.junit.Test;importjava.text.SimpleDateFormat;importjava.util.*;importjava.util.stream.Collectors;importstaticjava.util.Comparator.comparingLong;importstaticjava.util.stream.Collectors.*;/***@Author:*@Date:2018/12......
  • JavaScript 正则表达式
    基本使用 //定义正则表达式 constreg=/^\d{4}-\d{1,2}-\d{1,2}$/; conststr="2020-11-11"; //验证字符串是否符合规则 reg.test(str);元字符^表示开始部分等于xxx$表示结束部分等于xxx[]表示字符串中存在中括号中定义的字符,可以使用连字符,如a-z表示可以匹......
  • 简化代码————匿名内部类,正则表达式,Lambda
         正则表达式     错误示范     ......
  • JS-数学表达式正则表达式支持(包含希腊字母、小数点等)
    //技术状况规则/**evt:{target:{value:''}},row:{"propName":"""propRule":""}*/functioncheckRule(evt,row,propName,propRule){//匹配a=5,a>5,a<5,a≤6,a≥5等varrule1=/[ΆΈ-ώa-zA-z]+([1-9]......
  • 身份证号和手机号正则表达式脱敏
    /***身份证号脱敏*脱敏规则:保留前六后三,适用于15位和18位身份证号*@paramidNumber*@authorcy*@since2022-04-22/publicstaticStringdesensitizedIdNumber(StringidNumber){if(StringUtil.isStrNotEmpty(idNumber)){if(idNumber.length()==15){idNu......
  • go模拟三元表达式最简单的方式
    众所周知,Go语言本身并没有提供内置的三元表达式,但是我们可以使用一些技巧来模拟实现。下面是使用最短的代码实现Go的三元表达式:packagemainimport"fmt"funcmain(){x:=10y:=20max:=map[bool]int{true:x,false:y}[x>y]fmt.Println(max)}......
  • java程序new对象后加大括号{},匿名类,闭包,lamda表达式相关
     这种在源码中经常出现,所以我拿出来说一说步骤1 new一个匿名子类对象    我姑且叫这种情况为“匿名子类”吧,就是有这样的情况,你new一个类的时候直接加一对花括号,实际上已经创建了它的一个匿名子类。老实说,我第一次见到这种写法也是懵逼的。比如我有一个父类publicc......
  • 【转载】PHP 箭头函数( Lambda表达式 )
    参考箭头函数(php官方中文文档)Laravel10集合--learnku环境软件/系统版本说明windows10php8.2.5-nts-Win32-vs16-x64箭头函数要求>=7.4.0备注如果需要详细了解,请点击本文参考内的官网链接,本文只是简单记录浏览learnku中文Laravel文档的时候......
  • 组件的样式(含三元表达式)
    04-组件的样式import'../css/01.css'//导入样式functionApp(){varmyname="lucax"varobj={background:"red",fontSize:"40px"//font-size所有样式的-都改为用驼峰写法去替代}return(<div>......
  • 给定一个正整数字符串,使用Python正则表达式在其千分位上添加逗号
    大家好,我是皮皮。一、前言前几天在Python黄金青铜群【沐】问了一个Python正则表达式的问题,这里拿出来给大家分享下。题目:给定一个正整数字符串,如12345678、345678,使用正则表达式在其千分位上添加逗号,如12,345,678、345,678。二、实现过程这里ChatGPT给了一个答案,可以使用......