在java8中引入了很多新特性,其中最有亮點的就是函數式編程,例如lambda表達式,簡化書寫等.
我們先看一個關於Lambda的使用:
/**
* 輸出list
*/
@Test
public void test() {
String[] array = {"aaaa", "bbbb", "cccc"};
List<String> list = Arrays.asList(array);
//Java 7
for(String s:list){
System.out.println(s);
}
//Java 8
list.forEach(System.out::println);
}
其中list.forEach(System.out::println);就是Java 8中的Lambda寫法之一, 有沒有特別注意到輸出語句跟我們平時寫的syso語句不一樣,常規輸出語句是這樣的:
System.out.println(“hello world!”);
這裏面使用到了::,下面接詳細介紹:
雙冒號(::)
雙冒號(::)運算符在Java 8中被用作方法引用(method reference),方法引用是與lambda表達式相關的一個重要特性。它提供了一種不執行方法的方法。爲此,方法引用需要由兼容的函數接口組成的目標類型上下文。
Method References
You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it’s often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
關於方法引用的描述,摘自oracle官網
大致意思是,使用lambda表達式會創建匿名方法, 但有時候需要使用一個lambda表達式只調用一個已經存在的方法(將當前方法作爲一個參數傳遞給其他方法,其他方法去調用它,不做其它), 所以這纔有了方法引用!
以下是Java 8中方法引用的一些語法:
- 靜態方法引用(static method)語法:classname::methodname 例如:Person::getAge
- 對象的實例方法引用語法:instancename::methodname 例如:System.out::println
- 對象的超類方法引用語法: super::methodname
- 類構造器引用語法: classname::new 例如:ArrayList::new
- 數組構造器引用語法: typename[]::new 例如: String[]:new
如果上的語法太枯燥,那就通過一些例子來加強對它的理解:
靜態方法語法使用例子:
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author zhoufy
* @date 2019年2月20日 下午2:19:13
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan("com.zhoufy")
public class Demo {
@Test
public void test() {
List<String> list = Arrays.asList("aaaa", "bbbb", "cccc");
//靜態方法語法 ClassName::methodName
list.forEach(Demo::print);
}
public static void print(String content){
System.out.println(content);
}
}
類實例方法語法使用例子:
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author zhoufy
* @date 2019年2月20日 下午2:19:13
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan("com.zhoufy")
public class Demo {
@Test
public void test() {
List<String> list = Arrays.asList("aaaa", "bbbb", "cccc");
//對象實例語法 instanceRef::methodName
list.forEach(new Demo()::print);
}
public void print(String content){
System.out.println(content);
}
}
超類方法語法使用例子:
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author zhoufy
* @date 2019年2月20日 下午2:41:38
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan("com.zhoufy")
public class Example extends BaseExample{
@Test
public void test() {
List<String> list = Arrays.asList("aaaa", "bbbb", "cccc");
//對象的超類方法語法: super::methodName
list.forEach(super::print);
}
}
class BaseExample {
public void print(String content){
System.out.println(content);
}
}
類構造器語法使用例子:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
*
* @author zhoufy
* @date 2019年2月20日 下午2:19:13
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ComponentScan("com.zhoufy")
public class Example {
@Test
public void test() {
InterfaceExample com = Example::new;
Example bean = com.create();
System.out.println(bean);
}
}
interface InterfaceExample{
Example create();
}
如果是帶參數的構造器,示例如下:
/**
* @author zhoufy
* @date 2019年2月20日 下午2:19:13
*/
public class Example {
private String name;
Example(String name){
this.name = name;
}
public static void main(String[] args) {
InterfaceExample com = Example::new;
Example bean = com.create("hello world");
System.out.println(bean.name);
}
}
interface InterfaceExample{
Example create(String name);
}
這裏需要特別注意的是:Example 類並沒有implements InterfaceExample接口哦!!!
數組構造器語法使用例子:
import java.util.function.Function;
/**
* @author zhoufy
* @date 2019年2月20日 下午2:19:13
*/
public class Example {
public static void main(String[] args) {
Function <Integer, Example[]> function = Example[]::new;
Example[] array = function.apply(4); //這裏的4是數組的大小
for(Example e:array){
System.out.println(e); //如果輸出的話,你會發現會輸出4個空對象(null)
}
}
}
這裏是借用jdk自帶的java.util.function.Function類實現的,如果想要自定義接口
/**
*
* @author zhoufy
* @date 2019年2月20日 下午2:19:13
*/
public class Example {
public static void main(String[] args) {
Interface <Integer, Example[]> function = Example[]::new;
Example[] array = function.apply(4); //這裏的4是數組的大小
for(Example e:array){
System.out.println(e);
}
}
}
@FunctionalInterface
interface Interface<A, T>{
T apply(A a);
}