Java:lambda表达式

lambda表达式

简介

  • lambda 表达式不能独立执行,因此必须实现函数式接口,并且会返回一个函数式接口的对象。

语法如下:

()->结果表达式
参数->结果表达式
(参数1,参数2……参数n)->结果表达式

实现复杂方法时用代码块

lambda表达式实现函数式接口

函数式接口

函数式借口指的是仅包含一个抽象方法的接口,接口中的方法简单明了地说明了接口的用途,如线程接口Runnable、动作事件监听接口ActionListener等。

interface MyInterface{
	void method();
}

lambda表达式调用外部变量

lambda表达式无法改变局部变量

局部变量在lambda表达式中是以final形式存在的

interface VariableInterface1{
	void method();
}

public class VariableDemo1{
	public static void main(String[] args){
		int value = 100;
		VariableInterface1 v = ()->{
			int num = value - 90;
			value = 12; // 更改局部变量,此处会报错
		};
	}
}

lambda表达式可以更改类成员变量

类成员变量在lambda表达式中不是被final修饰的,所以lambda表达式可以改变其值

interface VariableInterface1{
	void method();
}

public class VariableDemo1{
	int value = 100;
	public static void main(String[] args){
		VariableInterface1 v = ()->{
			value = 12; 
		};
	}
}

方法的引用

引用静态方法

类名:静态方法名

interface StaticMethodInterface{
    int method(int a, int b);
}

public class StaticMethodDemo{
    static int add(int x, int y){
        return x + y;
    }

    public static void main(String[] args){
        StaticMethodInterface sm = StaticMethodDemo::add;
        int result = sm.method(15, 16);
        System.out.println(result);
    }
}

引用成员方法

对象名::成员方法名

import java.text.SimpleDateFormat;
import java.util.Date;

interface InstanceMethodInterface{
    String method(Date date);
}

public class InstanceMethodDemo{
    public String format(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }

    public static void main(String[] args){
        InstanceMethodDemo demo = new InstanceMethodDemo();
        InstanceMethodInterface im = demo::format;
        Date date = new Date();
        System.out.println("默认格式:" + date);
        System.out.println("接口输出的格式:" + im.method(date));
    }
}
默认格式:Sun Nov 07 15:35:12 CST 2021
接口输出的格式:2021-11-07

引用带泛型的方法

import java.util.HashSet;

interface ParadigmInterface<T>{
    int method(T[] t);
}

public class ParadigmDemo{
    //用于查找数组中的重复元素个数
    public static<T> int repeatCoount(T[] t){
        int arrayLength = t.length;
        HashSet<T> set = new HashSet<>();
        for (T tmp : t){
            set.add(tmp);
        }
        return arrayLength - set.size();
    }

    public static void main(String[] args){
        Integer a[] = {1,1,2,3,1,5,6,1,8,8};
        String s[] = {"王","李","王","赵","孙"};

        ParadigmInterface<Integer> p1 = ParadigmDemo::<Integer>repeatCoount;
        System.out.println("整数数组重复元素个数:" + p1.method(a));

        //方法名若不定义泛型,则默认使用接口已定义好的泛型
        ParadigmInterface<String> p2 = ParadigmDemo::repeatCoount;
        System.out.println("字符串数组重复元素个数:" + p2.method(s));
    }
}
整数数组重复元素个数:4
字符串数组重复元素个数:1

引用构造方法

引用无参构造方法

类名:new

interface ConstructorsInterface1{
    ConstructorsDemo1 action();
}

public class ConstructorsDemo1{
    public ConstructorsDemo1(){
        System.out.println("调用无参构造方法");
    }
    public ConstructorsDemo1(int i){
        System.out.println("调用有参构造方法,参数为:" + i);
    }

    public static void main(String[] args){
        ConstructorsInterface1 a = ConstructorsDemo1::new;
        ConstructorsDemo1 b = a.action();
    }
}

我发现在接口中用了ConstructorsDemo类型声明action方法,这样只能引用此类的构造方法,于是利用泛型改了改。

interface ConstructorsInterface1<T>{
    T action();
}

public class ConstructorsDemo1{
    public ConstructorsDemo1(){
        System.out.println("调用无参构造方法");
    }
    public ConstructorsDemo1(int i){
        System.out.println("调用有参构造方法,参数为:" + i);
    }

    public static void main(String[] args){
        ConstructorsInterface1<ConstructorsDemo1> a = ConstructorsDemo1::new;
        ConstructorsDemo1 b = a.action();
    }
}

引用有参构造方法

interface ConstructorsInterface1<T>{
    T action(int i);
}

public class ConstructorsDemo1{
    public ConstructorsDemo1(){
        System.out.println("调用无参构造方法");
    }
    public ConstructorsDemo1(int i){
        System.out.println("调用有参构造方法,参数为:" + i);
    }

    public static void main(String[] args){
        ConstructorsInterface1<ConstructorsDemo1> a = ConstructorsDemo1::new;
        ConstructorsDemo1 b = a.action(123);
    }
}

引用数组构造方法

类名[]:new

如果方法返回值是泛型,则可以返回一个数组类型。
既引用构造方法,又要返回数组类型结果,此时抽象方法的参数就是数组个数。抽象方法的参数可以决定返回的数组的长度,但数组中的元素并不是有值的,还需要再次赋值。

interface ArraysConsInterface<T>{
    T action(int n);
}

public class ArraysConsDemo{
    public static void main(String[] args){
        ArraysConsInterface<ArraysConsDemo[]> a = ArraysConsDemo[]::new;
        ArraysConsDemo array[] = a.action(3);
        array[0] = new ArraysConsDemo();
        array[1] = new ArraysConsDemo();
        array[2] = new ArraysConsDemo();
    }
}

Function接口

java.util.funcion包提供了许多预定义的函数式接口,没有实现任何功能。
最常用的接口是Function<T,R>接口

  • T:被操作的类型,可以理解为方法参数类型。
  • R:操作结果的类型,可以理解为方法的返回类型。

Function还提供了三个已实现的方法

Lambda表达式实现Function <T,R>接口

@FunctionalInterface
public interface Function<T, R> {
   R apply(T t);
}
import java.util.function.Function;

public class FunctionTest {
   public static void main(String[] args) {
      Function<Integer, Integer> f1 = i -> i*4;   // lambda      
      System.out.println(f1.apply(3));

      Function<Integer, Integer> f2 = i -> i+4;   // lambda      
      System.out.println(f2.apply(3));

      Function<String, Integer> f3 = s -> s.length();   // lambda      
      System.out.println(f3.apply("Adithya"));

      System.out.println(f2.compose(f1).apply(3));
      System.out.println(f2.andThen(f1).apply(3));

      System.out.println(Function.identity().apply(10));
      System.out.println(Function.identity().apply("Adithya"));
   }
}

12
7
7
16
28
10
Adithya

posted @ 2021-11-07 11:28  fristzzz  阅读(87)  评论(0)    收藏  举报