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-笔记的主要内容,如果未能解决你的问题,请参考以下文章