zoukankan      html  css  js  c++  java
  • Java的Lambda表达式和函数式接口

    Lambda表达式

    简介

    Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的 代码(将代码像数据一样进行传递)。可以替换匿名内部类,函数式接口。

    Lambda 是jdk1.8后有的。

    例如:匿名内部类  VS   Lambda表达式

    //原来使用匿名内部类
    TreeSet<Person> ts = new TreeSet<Person>(new Comparator<Person>() {
    	@Override
    	public int compare(Person o1, Person o2) {
    		return o1.getName().compareTo(o2.getName());
    	}
    });
    //JDK1.8后可以使用Lambda
    Comparator<Person> com = (x,y)->x.getName().compareTo(y.getName());
    TreeSet<Person> ts2 = new TreeSet<Person>(com);
    
    //匿名内部类                                           
    Runnable r1 = new Runnable() {                    
    	@Override                                     
    	public void run() {                           
    		System.out.println("run...");             
    	}                                             
    };                                                
    //Lambda表达式                                       
    Runnable r2 = () -> System.out.println("run..."); 
    

    语法

    Lambda表达式:Java8以后,引入了“->”操作符
        “->”左侧:参数列表
        “->”右侧:所需要执行的功能,即Lambda体

    语法格式一:无参数无返回值
    	()-> System.out.println("Hello Lambda ");
    语法格式二: 一个参数,无返回
    	//x表示变量,变量名x任意
    	(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 注解,这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。

    自定义函数式接口

    @FunctionalInterface
    public interface MyFun {
    	public Integer getValue(Integer num);
    }
    
    @FunctionalInterface
    public interface Myfunc<T> {
    	public T getValue(T t);
    }
    

    作为参数传递 Lambda  表达式,实参即Lambda表达式必须与函数接口的参数一致

    @Test
    public void test07() {
    	String s = toOperateString((x) -> x.toUpperCase(), "goodman");
    	System.out.println(s);
    	String s2 = toOperateString((x)->x.toLowerCase(), s);
    	System.out.println(s2);
    }
    
    //测试 作为参数传递 Lambda 表达式
    public String toOperateString(Myfunc<String> fun, String origin) {
    	String res = fun.getValue(origin);
    	return res;
    }
    

    内置的函数式接口

    Java8 内置的四大核心函数式接口      
                            
    Consumer<T> : 消费型接口     
            void accept(T t);  
                            
    Supplier<T> : 供给型接口     
            T get();           
                            
    Function<T, R> : 函数型接口  
            R apply(T t);      
                            
    Predicate<T> : 断言型接口    
            boolean test(T t);

    其他类型的一些函数式接口
      除了上述得4种类型得接口外还有其他的一些接口供我们使用:
        1)BiFunction<T, U, R>
          参数类型有2个,为T,U,返回值为R,其中方法为 R apply(T t, U u)
        2)UnaryOperator<T>(Function子接口)
          参数为T,对参数为T的对象进行一元操作,并返回T类型结果,其中方法为 T apply(T t)
        3)BinaryOperator<T>(BiFunction子接口)
          参数为T,对参数为T得对象进行二元操作,并返回T类型得结果,其中方法为 T apply(T t1, T t2)
        4)BiConsumer(T, U)
          参数为T,U  无返回值,其中方法为 void accept(T t, U u)
        5)ToIntFunction<T>、ToLongFunction<T>、ToDoubleFunction<T>
          参数类型为T,返回值分别为int,long,double,分别计算int,long,double得函数。
        6)IntFunction<R>、LongFunction<R>、DoubleFunction<R>
          参数分别为int,long,double,返回值为R。

    方法引用和构造器引用

    方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。
    如下三种主要使用情况 :
      对象 :: 实例方法
      类 :: 静态方法
      类 :: 实例方法

    当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。

    Consumer con = (x) -> System.out.println(x);
    //等价于
    Consumer con2 = System.out::println;
    
    BinaryOperator<Double> bo = (x,y) -> Math.pow(x, y);
    //等价于
    BinaryOperator<Double> bo2 = Math::pow;
    

    注意:实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!

    构造器引用

    格式:      类名::new

    Function<Integer, MyClass> fun = (x) -> new MyClass(x);
    //等价于
    Function<Integer, MyClass> fun2 = MyClass::new;
    

     数组

    Function<Integer, Integer[]> fun = (x) -> new Integer[x];
    //等价于
    Function<Integer, Integer[]> fun2 = Integer[]::new;
    

    ********************************

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    [leetcode-648-Replace Words]
    [leetcode-647-Palindromic Substrings]
    [leetcode-646-Maximum Length of Pair Chain]
    [leetcode-645-Set Mismatch]
    [leetcode-459-Repeated Substring Pattern]
    [leetcode-636-Exclusive Time of Functions]
    [leetcode-644-Maximum Average Subarray II]
    iOS开发之使用XMPPFramework实现即时通信(三)
    Oracle 内置sql函数大全
    Oracle 中的sql函数以及分页
  • 原文地址:https://www.cnblogs.com/htj10/p/15252655.html
Copyright © 2011-2022 走看看