您的位置:首页 > 编程语言 > Java开发

Java8新特性-004-方法、构造器、数组引用

2017-12-27 11:55 501 查看

方法引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!(实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!)

方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。

如下三种主要使用情况:

1.对象::实例方法
2.类::静态方法
3.类::实例






应用条件

对象::实例方法名、类::静态方法名——应用条件:

要实现的Lambda表达式中的抽象方法具体实现的时候调用了另外一个对象的方法(类的静态方法),如果这两个方法(自己的抽象方法、另一个对象的方法)的参数和返回值一致,那么可以直接使用。

总结:参数和返回值类型一致。

类::实例方法名——应用条件;

Lambda表达式有两个参数,第一个参数作为实例方法的调用者,第二个参数作为这个实例方法的参数,且返回值类型和Lambda表达式返回值的类型一致时,可用(类名::实例方法名指的是第一个参数的类和实例方法)。

如:boolean test(String str1,String str2) ==> (str1,str2) -> str1.equals(str2),其中str1.equals(str2)满足上述条件,就可以写为:String::eauals;

总结:

- 参数一作为实例方法的调用者;

- 参数二作为实例方法的参数;

- 返回值类型和Lambda表达式一致;

测试代码

TestMethodRef.java

package java8.method.constructor;

import java.io.PrintStream;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.S
4000
upplier;

import org.junit.Test;

public class TestMethodConstructor {
/**
* 方法的引用:
*  1.若Lambda中的内容有方法已经实现了,那么我们可以使用“方法引用”,
*      可以理解为方法引用是Lambda表达式的另外一种形式
*  2.方法引用的三种形式:
*      2.1.对象::实例方法名
*      2.2.类::静态方法名
*      2.3.类::实例方法名
*  3.应用条件
*      3.1.对象::实例方法名、类::静态方法名——应用条件:
*          要实现的Lambda表达式中的抽象方法具体实现的时候调用了另外一个对象的方法(类的静态方法),
*          如果这两个方法(自己的抽象方法、另一个对象的方法)的参数和返回值一致,
*          那么可以直接使用。
*          总结:参数和返回值类型一致。
*      3.2.类::实例方法名——应用条件;
*          Lambda表达式有两个参数,第一个参数作为实例方法的调用者,第二个参数作为这
*          个实例方法的参数,且返回值类型和Lambda表达式返回值的类型一致时,可用
*          (类名::实例方法名指的是第一个参数的类和实例方法)。
*          如:boolean test(String str1,String str2) ==> (str1,str2) -> str1.equals(str2);
*          其中str1.equals(str2)满足上述条件,就可以写为:String::eauals;
*          总结:
*              - 参数一作为实例方法的调用者;
*              - 参数二作为实例方法的参数;
*              - 返回值类型和Lambda表达式一致;
*/

/**
* 2.1.对象::实例方法名
*/
@Test
public void testMethodRef1() {
PrintStream out = System.out;
/**
*  Lambda对象 = 另一个对象::另一个对象符合要求的方法名。
*/

/**
* 参数和返回值一致:
* accept: void accept(String str);
* println: void println(String str);
*/
Consumer<String> consumer = out::println;

consumer.accept("对象::实例方法名!");
}

//////////////////////////////////////////////////////////////////////////////
/**
* 2.2.类::静态方法名
*/
/**
* 规则和2.1类似,都是参数和返回值对应
*/
@Test
public void testMethodRef2() {
/**
* 同样的,参数和返回值要一致:
* int Comparator.compare(Integer i1, Integer i2)
* int Integer.compare(Integer i1, Integer i2)
*/
Comparator<Integer> comparator = Integer::compare;

TreeSet<Integer> treeSetInteger = new TreeSet<>(comparator);
treeSetInteger.add(10);
treeSetInteger.add(-1);
treeSetInteger.add(20);
Iterator<Integer> iterator = treeSetInteger.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next() + "\t");
}
}
//////////////////////////////////////////////////////////////////////////////
/**
* 2.3.类::实例方法名
*/
/**
* 应用条件:
*  Lambda表达式有两个参数,第一个参数作为实例方法的调用者,第二个参数作为这个实例
*  方法的参数,且返回值类型和Lambda表达式返回值的类型一致时,可用(类名::实例方法名
*      指的是第一个参数的类和实例方法)。
*  如:boolean test(String str1,String str2) ==> (str1,str2) -> str1.equals(str2);
*      其中str1.equals(str2)满足上述条件,就可以写为:String::eauals;
*/
@Test
public void testMethodRef3() {
/**
* 参数和返回值一致:
*  - 参数一作为实例方法的调用者;
*  - 参数二作为实例方法的参数;
*  - 返回值类型和Lambda表达式一致;
*/
BiPredicate<String, String> biPredicate = String::equals;
System.out.println(biPredicate.test("中国", "日本"));
}
}




构造器引用

格式: ClassName::new

与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽象方法的参数列表一致!



测试代码

TestConstuctorRef.java

package java8.method.constructor;

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

import org.junit.Test;

public class TestConstuctorRef {

/**
* 构造器引用:
*   1.格式:
*      类名::new
*   2.应用条件
*      Lambda表达式的内容刚好只有这一个新建对象的语句,新建的对象也刚好是这个Lambda
*      表达式的返回值,并且Lambda表达式的参数刚好是新建对象的构造器的参
*      数(对应去调用这个构造器)。
*/

@Test
public void testConstructor1() {
/**
* 应用条件:
*  1.新建的对象刚好是Lambda表达式的返回值类型;
*  2.Lambda表达式的参数刚好是这个构造器的参数值(对应去调用这个构造器);
*/
// 对应:空参构造器
Supplier<Person> supplierPerson = Person::new;

System.out.println(supplierPerson.get());

// 对应:一个参数的构造器,String
Function<String, Person> functionPerson = Person::new;  // <String, Person> -->参数,返回值
System.out.println(functionPerson.apply("周杰伦"));
}
}

class Person {
private String name = "冯强";

// 构造器一
public Person() {

}

// 构造器二
public Person(String name) {
this.name = name;
}

@Override
public String toString() {
return "Person [name=" + name + "]";
}
}




数组引用

格式: 数组类型[] :: new



测试代码

TestArrayRef.java

package java8.method.constructor;

import java.util.function.Function;

import org.junit.Test;

public class TestArrayRef {
/**
* 数组引用:
*  1.格式
*      数组类型[]::new;
*  2.引用条件:
*      和构造器引用的条件是一样的(返回值类型,参数对应构造器),只是写法是专有的。
*/
@Test
public void testArrayRef() {
/**
* String[] apply(Integer i); --> String[]::new; --> new String(i);
*/
Function<Integer, String[]> functionStringArray = String[]::new;

String[] apply = functionStringArray.apply(10);
System.out.println("数组长: " + apply.length);
}
}




其它

源码下载

关注下方公众号,回复:Java8.code


欢迎加入交流群:451826376

更多信息:www.itcourse.top

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: