函數式編程-Java8語法分析

什麼是函數式編程?

是一種編程模型,把計算機中的運算看做數學中的函數計算,並且避免了狀態及變量的概念 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);
        }
    }
}


Lambda表達式能夠簡化代碼一方面是如上的函數式接口,另一方面是方法的引用

方法引用

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()));

    }
}







發佈了98 篇原創文章 · 獲贊 41 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章