Java8-03-笔记

Posted 寻7

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8-03-笔记相关的知识,希望对你有一定的参考价值。

Java8-03-笔记

方法引用、构造器引用和数组引用

1、基本定义

  • @定义看不懂没关系,先有个概念,看完所有内容后再回头看看就明白了,这些提前写出来是为了方便我自己看的@
  • @个人感觉这块知识点不太好用,Lambda表达式可以说的匿名函数格式的简化,这块又是对Lambda格式的简化,格式太过简单,使用时脑子跟不上#_#,见得多用的多应该就好了@
  • 方法引用:若Lambda体中的功能,已经有方法提供了实现,可以使用方法引用【方法引用能不能使用主要是看->右侧的方法体,和左侧的参数列表无关;当使用方法引用时,左右都需要考虑】(可以将方法引用理解为Lambda表达式的另外一种表现形式,其实构造器引用和数组引用本质上都是的)。
  • 方法引用主要有三种语法格式:
  • 1.对象的引用 :: 实例方法,即,对象 :: 实例方法
  • 2.类名 :: 静态方法名
  • 3.类名 :: 实例方法名
  • 注意:
  • 方法引用所 引用的方法的参数列表和返回值类型,需要与函数式接口中的抽象方法的参数列表和返回值类型保持一致!
  • 针对第三种(类名 :: 实例方法名),若Lambda表达式参数列表中的第一个参数是实例方法的调用者,第二个参数(或无参)是实例方法的入参时,采用此种方法引用格式。
  • 构造器引用:构造器的参数列表,需要与函数式接口中的参数列表保持一致!格式: 类名 :: new
  • 数组引用:类型[] :: new

2、方法引用

  • 说明:代码中的@222@、@333@分别代表个人总结的Lambda表达式使用三要素(个人好理解,毕竟笔记主要是为了我来看的$)
  • @111@函数式接口:这里使用的是java8内置的函数式接口
  • @222@有方法的入参是函数式接口的实现类,并且该方法内部会使用该实现类:这里可以将函数式接口对象的抽象方法调用加个理解为方法
  • @333@调用上面的方法时,使用Lambda表达式对函数式接口进行赋值即可:这里就是对函数式接口赋值
  • 对象 :: 实例方法名
package com.sunstone.ref;

import com.sunstone.lambda.Employee;
import org.junit.Test;

import java.io.PrintStream;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class TestMethodRef 

    @Test
    public void test1()
        Consumer<String> con1 = (x) -> System.out.println(x);    //@333@
        con1.accept("hello");        //@222@

        /*
        public final class System 
             * The "standard" output stream. This stream is already
             * open and ready to accept output data. Typically this stream
             * corresponds to display output or another output destination
             * specified by the host environment or user.
             * <p>
             * For simple stand-alone Java applications, a typical way to write
             * a line of output data is:
             * <blockquote><pre>
             *     System.out.println(data)
             * </pre></blockquote>
            public final static PrintStream out = null;
            ...略
        
        */
        PrintStream ps =System.out;
        Consumer<String> con2 = (str) -> ps.println(str);       //@333@
        con2.accept("sun");     //@222@

        //con1不太容易看出能否使用方法引用,con2则较为容易看出:
        //  ->右侧的方法体已经有方法提供了实现(对象ps的实例方法println(str)),可以使用方法引用
        Consumer<String> con3 = ps :: println;      //@333@
        con3.accept("stone");       //@222@

        //换一种常见表达
        Consumer<String> con4 = System.out :: println;      //@333@
        con4.accept("石头");      //@222@

        //con4就是我们常用的表达形式
        //注意看下System.out对象的println方法的参数列表和返回值
        //     与 函数式接口Consumer的抽象方法accept方法的参数列表和返回值一致!
        /*
        public class PrintStream extends FilterOutputStream
            implements Appendable, Closeable

             * Prints a String and then terminate the line.  This method behaves as
             * though it invokes <code>@link #print(String)</code> and then
             * <code>@link #println()</code>.
             *
             * @param x  The <code>String</code> to be printed.
            public void println(String x) 
                synchronized (this) 
                    print(x);
                    newLine();
                
            
            ...略
        
        */
    
    
    @Test
    public void test2()
        Employee employee = new Employee("雪豹",17,99999);

        Supplier<Integer> sup1 = () -> employee.getAge();       //@333@
        System.out.println(sup1.get());     //@222@
        
        Supplier<Integer> sup2 = employee :: getAge;
        System.out.println(sup2.get());
    

  • 类名 :: 静态方法名
package com.sunstone.ref;

import org.junit.Test;

import java.util.Comparator;
import java.util.function.BiFunction;


public class TestMethodRef 

    @Test
    public void test3()
        BiFunction<Double,Double,Double> biFunction1 = (x,y) -> Math.max(x,y);      //@333@
        System.out.println(biFunction1.apply(1.7,2.1));     //@222@

        //Lambda表达式右侧的Lambda体,有静态方法已经提供了实现所以可以使用方法引用
        BiFunction<Double,Double,Double> biFunction2 = Math :: max;     //@333@
        System.out.println(biFunction2.apply(1.7,2.1));     //@222@

        /*
        注意:方法引用中的静态方法max的参数列表和返回值 与 函数式接口biFunction1中的参数列表和返回值一致
        public final class Math 
            public static double max(double a, double b) 
                if (a != a)
                    return a;   // a is NaN
                if ((a == 0.0d) &&
                        (b == 0.0d) &&
                        (Double.doubleToRawLongBits(a) == negativeZeroDoubleBits)) 
                    // Raw conversion ok since NaN can't map to -0.0.
                    return b;
                
                return (a >= b) ? a : b;
            
            ...略
        
        */
    
    
    @Test
    public void test4()
        Comparator<Integer> comparator1 = (x,y) -> Integer.compare(x,y);
        Comparator<Integer> comparator2 = Integer :: compare;
    
    

  • 类名 :: 实例方法名
package com.sunstone.ref;

import com.sunstone.lambda.Employee;
import org.junit.Test;

import java.util.function.*;

public class TestMethodRef 

    @Test
    public void test5()

        //若Lambda表达式参数列表中的
        // 第一个参数是实例方法的调用者, 
        			//【其实只要这一条就够了,一旦参数列表中有参数是方法的调用者,就使用该格式】
        // 第二个参数(或无参)是实例方法的入参时,
        // 采用此种方法引用格式
        BiPredicate<String,String> bp1 = (x,y) -> x.equals(y);      //@333@
        System.out.println(bp1.test("stone","石头"));     //@222@
            //equals并不是静态方法
        BiPredicate<String,String> bp2 = String :: equals;      //@333@
        System.out.println(bp1.test("stone","石头"));     //@222@


        Employee employee = new Employee("雪豹",17,99999);
        Function<Employee,String> fun1 = (e) -> e.toString();       //@333@
        System.out.println(fun1.apply(employee));       //@222@

        Function<Employee,String> fun2 = Employee :: toString;       //@333@
        System.out.println(fun2.apply(employee));       //@222@
    


3、构造器引用

package com.sunstone.ref;

import com.sunstone.lambda.Employee;
import org.junit.Test;

import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

public class TestConstructRef 

    @Test
    public void test1()

		//构造器就是为了new对象,所以一定有返回值
		//因此函数式接口的选择首先是要有返回值,
		
		//不管是无参还是有参,构造器格式都是一样的 类名::new
		//调用哪个构造器就看入参了
		//所以选择函数式接口时注意入参列表个数就好了
		
		
        //无参构造
        Supplier<Employee> sup1 = () -> new Employee();     //@333@
        System.out.println(sup1.get());     //@222@

        Supplier<Employee> sup2 = Employee :: new;     //@333@
        System.out.println(sup2.get());     //@222@

        //有参构造(1个入参)
        Function<String,Employee> sup3 = (name) -> new Employee(name);     //@333@
        System.out.println(sup3.apply("stone"));     //@222@

        Function<String,Employee> sup4 = Employee :: new;     //@333@
        System.out.println(sup4.apply("石头"));     //@222@

        //有参构造(2个入参)
        BiFunction<String,Integer,Employee> sup5 = (name,age) -> new Employee(name,age);     //@333@
        System.out.println(sup5.apply("stone",17));     //@222@

        BiFunction<String,Integer,Employee> sup6 = Employee :: new;     //@333@
        System.out.println(sup6.apply("石头",21));     //@222@
    


4、数组引用

package com.sunstone.ref;

import com.sunstone.lambda.Employee;
import org.junit.Test;

import java.util.function.Function;

public class TestArrayRef 

	//数组引用格式更加固定了
	//一个入参(元素个数),一个返回值(数组对象) 首选函数式接口Function<T,R>
	//引用格式:Function<Integer,类名[]> = 类名[]::new
    @Test
    public void test1()
        Function<Integer,String[]> fun1 = (args) -> new String[args];       //@333@
        String[] strs1 = fun1.apply(10);        //@222@
        System.out.println(strs1.length);

        Function<Integer,String[]> fun2 = String[] :: new;       //@333@
        String[] strs2 = fun2.apply(20);        //@222@
        System.out.println(strs2.length);

        Function<Integer, Employee[]> fun3 = (args) -> new Employee[args];       //@333@
        Employee[] emps1 = fun3.apply(10);        //@222@
        System.out.println(emps1.length);

        Function<Integer, Employee[]> fun4 = Employee[] :: new;       //@333@
        Employee[] emps2 = fun4.apply(20);        //@222@
        System.out.println(emps2.length);
    


以上是关于Java8-03-笔记的主要内容,如果未能解决你的问题,请参考以下文章

android驱动开发第六章心得笔记

Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码

Chrome笔记本如何成为安全专家的首选笔记本电脑

算法笔记:动态规划——背包问题(上)

算法笔记:动态规划——背包问题(上)

Java8_Chapter03