什麼是函數式編程?
是一種編程模型,把計算機中的運算看做數學中的函數計算,並且避免了狀態及變量的概念 f(x)
函數式接口
第一種:就是在一個接口中定義唯一的一個抽象方法,那麼這個接口就是函數式接口
public interface FunctionInterfaceDemo {
void sayHello();
}
第二種:通過註解的方式@FunctionalInterface聲明,加註解相當於加了一個強制性的約束
@FunctionalInterface
public interface FunctionInterfaceDemo {
void sayHello();
}
函數式接口裏面也可以有實現方法,好處是修改接口後不需要改實現,使得接口在發佈之後仍然可以升級
@FunctionalInterface
public interface FunctionInterfaceDemo {
void sayHello();
//java8兩種實現方法方式
static void sayHi(){
System.out.println("say hi");
}
default void doAnything(){
System.out.println("do anything");
}
}
public class Main {
public static void main(String[] args) {
FunctionInterfaceDemo fi = new FunctionInterfaceDemo() {
@Override
public void sayHello() {
System.out.println("say hello");
}
};
fi.sayHello();
fi.doAnything();
FunctionInterfaceDemo.sayHi();
}
}
重寫父類的方法不違背函數式接口的定義
例如重寫equals或toString
@FunctionalInterface
public interface FunctionInterfaceDemo {
void sayHello();
//java8兩種實現方法方式
static void sayHi(){
System.out.println("say hi");
}
default void doAnything(){
System.out.println("do anything");
}
boolean equals(Object object);
}
Lambda表達式
語法組成:
1. 一個括號內用逗號分隔的形式參數,參數是函數式接口裏面的方法參數
2. 一個箭頭號 ->
3. 方法體或者代碼塊
(parameters) -> expression
public class MainDemo2 {
public static void main(String[] args) {
//傳統方式啓動一個線程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("I am thread test1");
}
}).start();
//Lambda簡化後
new Thread(()->{
System.out.println("I am thread test2");
}).start();
//Lambda繼續簡化,整個代碼塊只有一行代碼,而這一行代碼就是表達式的返回值的話就可以省略代碼塊
new Thread(()-> System.out.println("I am thread test3")).start();
}
}
public class MainDemo3 {
public static void main(String[] args) {
List<String> words = Arrays.asList("a", "b", "c");
//傳統方式比較排序
// words.sort(new Comparator<String>() {
// @Override
// public int compare(String o1, String o2) {
// return o2.compareTo(o1);
// }
// });
//Lambda表達式實現
// words.sort((String o1,String o2) -> {
// return o2.compareTo(o1);
// });
//繼續優化
words.sort((o1,o2) ->o2.compareTo(o1));
for (String word: words) {
System.out.print(word);
}
}
}
方法引用
1. 引用靜態方法 String::valueOf
2. 引用對象的實例方法 x::toString
3.引用某個類型的任意對象的實例方法 String::toString
4.引用類構造函數 String::new
public class PersonInfo implements Comparable<PersonInfo> {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(PersonInfo o) {
return this.getName().compareTo(o.getName());
}
public int compare(PersonInfo p1 , PersonInfo p2){
return p1.getName().compareTo(p2.getName());
}
}
/**
* Created by xingyuchao on 2018/1/19.
* 工廠方法,將PersonInfo包裝成函數式接口的方式
*/
public class PersonInfoFactory {
private Supplier<PersonInfo> supplier;
public PersonInfoFactory(Supplier<PersonInfo> supplier){
this.supplier = supplier;
}
public PersonInfo getPerson(){
return supplier.get();
}
}
public class MainDemo4 {
public static void main(String[] args) {
//引用類構造函數 String::new
PersonInfoFactory personInfoFactory = new PersonInfoFactory(PersonInfo::new);
List<PersonInfo> personInfoList = new ArrayList<>();
PersonInfo personInfo1 = personInfoFactory.getPerson();
personInfo1.setName("xingyuchao");
personInfoList.add(personInfo1);
PersonInfo personInfo2 = personInfoFactory.getPerson();
personInfo2.setName("admin");
personInfoList.add(personInfo2);
PersonInfo personInfo3 = personInfoFactory.getPerson();
personInfo3.setName("china");
personInfoList.add(personInfo3);
//傳統方式
personInfoList.sort(new Comparator<PersonInfo>() {
@Override
public int compare(PersonInfo o1, PersonInfo o2) {
return 0;
}
});
print(personInfoList);
//引用對象的實例方法 x::toString
//personInfoList.sort(personInfo1::compare);
//引用某個類型的任意對象的實例方法 String::toString
//personInfoList.sort(PersonInfo::compareTo);
//引用靜態方法 String::valueOf
personInfoList.sort(MainDemo4::myCompare);
print(personInfoList);
}
public static void print(List<PersonInfo> personInfos){
personInfos.forEach(personInfo -> System.out.print(personInfo.getName()+" "));
System.out.println();
}
private static int myCompare(PersonInfo p1 , PersonInfo p2){
return p1.getName().compareTo(p2.getName());
}
}
流式操作
根據返回結果:分爲中間操作和最終操作(flume風格 鏈式操作)
根據併發性區分: 串行和並行操作
Stream.sequential()
Stream.parallel()
中間操作
Filter過濾器
Sorted 排序
Distinct
SubStream 獲取子流
終止操作
forEach
findFirst
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class MainDemo5 {
static List<Person> person = new ArrayList<Person>(){
{
add(new Person("admin",22));
add(new Person("xingyuchao",25));
}
};
public static void main(String[] args) {
// person.forEach(
// person ->{
// person.setAge(person.getAge() + 5);
// System.out.println(person.toString());
// });
// 過濾小於24歲的
person.stream().filter(person -> person.getAge()>24).forEach( person -> System.out.println(person.toString()));
}
}