java8 - 行爲參數化

行爲參數化:

幫助我們處理頻繁變更的需求的一種軟件開發模式;在開發中我們可以定義一段不需要馬上執行的代碼塊,在需要的地方通過參數傳遞的方式,將這段定義好的代碼傳遞給方法使用,在方法的內部完成不同的行爲

案例: 在一個班級中,學生的性格、愛好、身高、年齡、性別等都是有差異的,現在我需要找出身高1.5米的學生 和 男學生

在java8之前使用接口完成行爲參數化
// 學生類
public class Student {

    private String height;
    private String sex;
    private int age;

   ---getter、setter---
   
    public Student(String height, String sex, int age) {
        super();
        this.height = height;
        this.sex = sex;
        this.age = age;
    }

}
// 定義接口
public interface StuPredicate {

    boolean compare(Student student);

}
// 年齡比較:大於10歲
public class StudentAge implements StuPredicate {

    @Override
    public boolean compare(Student student) {
        return student.getAge() > 10;
    }
}

// 性別是男的
public class StudentSex implements StuPredicate {

    @Override
    public boolean compare(Student student) {
        return "男".equals(student.getSex());
    }

}
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(new Student("145", "男", 10), new Student("141", "男", 12),
                new Student("140", "女", 11), new Student("138", "女", 13), new Student("140", "男", 10),
                new Student("144", "nv", 12), new Student("142", "男", 13));
        
        // 傳入不同的實現,實現不同的行爲
        List<Student> list1 = filter(students, new StudentSex()); // 篩選出男生
        List<Student> list2 = filter(students, new StudentAge()); // 刪除出年齡大於10歲的學生
    }

    public static List<Student> filter(List<Student> stus, StuPredicate stuPredicate) {
        List<Student> resList = new ArrayList<Student>();
        for (Student student : resList) {
            if (stuPredicate.compare(student)) {
                resList.add(student);
            }
        }
        return resList;
    }
java8-使用方法引用

方法引用是java 8新加入的特性,可以理解爲Lambda表達式的快捷寫法,方法引用顯式的指明方法名稱去調用實現好的的方法
方法引用的定義: 目標引用 :: 目標方法(注意加粗的 :: 符號) ,示例:String::length
引用String類中的length方法 同 (String s)-> s.length()

public class Student {

    private String height;
    private String sex;
    private int age;

    ---getter、setter---
    
    public Student(String height, String sex, int age) {
        super();
        this.height = height;
        this.sex = sex;
        this.age = age;
    }

	// 是男的學生(注意:static 方法)
    public static boolean compareSex(Student student) {
       return "男".equals(student.getSex());
    }
	// 大於10歲(注意:static 方法)
    public static boolean compareAge(Student student) {
        return student.getAge() > 10;
    }
}
   public static void main(String[] args) {
        List<Student> students = Arrays.asList(new Student("145", "男", 10), new Student("141", "男", 12),
                new Student("140", "女", 11), new Student("138", "女", 13), new Student("140", "男", 10),
                new Student("144", "nv", 12), new Student("142", "男", 13));
        
        // 方法引用
        List<Student> list1 = filter(students, Student::compareAge); // 篩選出男生
        List<Student> list2 = filter(students, Student::compareSex); // 刪除出年齡大於10歲的學生
    }

    public static List<Student> filter(List<Student> stus, Predicate<Student> stuPredicate) {
        List<Student> resList = new ArrayList<Student>();
        for (Student student : resList) {
            if (stuPredicate.test(student)) {
                resList.add(student);
            }
        }
        return resList;
    }
java8-lambda表達式
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(new Student("145", "男", 10), new Student("141", "男", 12),
                new Student("140", "女", 11), new Student("138", "女", 13), new Student("140", "男", 10),
                new Student("144", "nv", 12), new Student("142", "男", 13));

		// Lambda表達式
        List<Student> list1 = filter(students, s -> "男".equals(s.getSex())); // 篩選出男生
        List<Student> list2 = filter(students, s -> s.getAge() > 10); // 刪除出年齡大於10歲的學生

    }

    public static List<Student> filter(List<Student> stus, Predicate<Student> stuPredicate) {
        List<Student> resList = new ArrayList<Student>();
        for (Student student : resList) {
            if (stuPredicate.test(student)) {
                resList.add(student);
            }
        }
        return resList;
    }
總結:
  • java 8之前能通過接口或者匿名內部類去實現行爲的參數化,如果有不同的行爲就要去實現接口開發不同的方法
  • 方法引用可以重複使用現有的方法定義,並像Lambda一樣傳遞它們,在某些情況下,比起使用Lambda表達式,它們似乎更易讀,感覺也更自然
  • 方法引用的語法:目標引用 :: 目標方法 Lambda表達式讓代碼變得更簡潔,但是對於不熟悉的開發人員來說,理解有點過於困難
  • 行爲參數化可讓代碼更好地適應不斷變化的要求
  • 行爲參數化讓一個方法接受多個不同的行爲作爲參數,並在內部使用它們, 完成不同行爲的能力
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章