策略模式,講這個模式的文章不少,但都缺少一個按部就班的過程。講lambda表達式的文章也不少,但基本都是堆砌一堆的概念,不多帶有本身的看法。博主一時興起,想寫一篇這兩者的文章。須要說明的是,在看這篇文章的時候,請忘記全部的概念。容博主一步一步的帶大家入坑。java
假設咱們有一個Hero類,其UML圖以下
這個時候,咱們有一個需求:算法
這時,咱們先封裝一個要根據type類型來篩選Hero的方法ide
public static List<Hero> getHero(List<Hero> heroList, String type){ List<Hero> result = new ArrayList<Hero>(); for(Hero hero : heroList){ if(type.equals(hero.getType())){ result.add(hero); } } return result; }
而後呢,作以下調用性能
getHero(heroList, "刺客");
忽然有一天,產品忽然改需求,如今的需求是spa
也很簡單嘛,再加一個重載的getHero方法就能夠嘛,重載的getHero(List
public static List<Hero> getHero(List<Hero> heroList, int stature){ List<Hero> result = new ArrayList<Hero>(); for(Hero hero : heroList){ if(hero.getStature() > stature){ result.add(hero); } } return result; }
而後呢,作以下調用對象
getHero(heroList, 170);
又過了幾日,產品喪心病況的又改需求,如今最新的需求是blog
固然,你或許說了,能夠再加一個getHero(List
稍微介紹一下策略模式
策略模式
意圖:策略模式定義了一系列的
算法,並將每個
算法封裝起來,並且使他們能夠相互替換,讓算法獨立於使用它的客戶而獨立變化。
主要解決:在有多種算法類似的狀況下,使用 if...else 所帶來的複雜和難以維護。產品
什麼時候使用:一個系統有許多許多類,而區分它們的只是他們直接的行爲。
如何解決:將這些算法封裝成一個一個的類,任意地替換。
ps:在這裏,上面的算法指的就是上面提到的判斷條件。咱們將判斷條件封裝爲相應的類。
此時代碼結構以下圖所示
那麼此時的getHero方法以下所示
public static List<Hero> getHero(List<Hero> heroList, Predicate<Hero> predicate){ List<Hero> result = new ArrayList<Hero>(); for(Hero hero : heroList){ if(predicate.test(hero)){ result.add(hero); } } return result; }
而後呢,根據需求作以下調用,想找那種類型的Hero,就傳那種類型的Predicate進去。
getHero(heroList,new TMPredicate());
但是呢,機智的你又發現了一個缺陷,每次新增一個算法,要新加一個實現類。因而,機智的你提出,利用匿名內部類來作調用,不寫實現類,因而調用代碼變成下面這樣
getHero(heroList,new Predicate<Hero>() { @Override public boolean test(Hero t) { return t.getStature() > 170 && "刺客".equals(t.getType()); } });
機智的你忽然間又以爲:這麼寫,佔用了太多的行數,看起來不夠美觀,因而,你決定用lambda表達式來改寫,因而代碼最終變成下面的樣子
getHero(heroList,(t)->t.getStature() > 170 && "刺客".equals(t.getType()));
好了,到這裏就結束了,是否是比咱們最開始的版本簡潔了很多,代碼優雅了不少。lambda主要的目的就是提供一個更加簡潔的代碼結構,可是對於初學者,它可能反而增長閱讀的難度。
固然,lambda表達式除了能簡化代碼代碼意外,還能並行處理元素,充分利用多核CPU的性能,例以下面的代碼
import java.util.Arrays; import java.util.List; public class Demo7 { public static void main(String[] args) { List<String> values = Arrays.asList("1","2","3","4"); print(values); } public static void print(List<String> values){ values.parallelStream().forEach(System.out :: println);//System.out表示對象,println表示方法 } }
輸出以下
3 4 1 2
本文以循序漸近的方式說明了,咱們爲何要用策略模式以及如何用lambda表達式改寫策略模式。但願你們有所收穫。
《JAVA8實戰》