使用Java 8 Lambda簡化Decorator設計模式
張益裕 Michael Chang
- 恆逸教育訓練中心-資深講師
- 技術分類:程式設計
如果你需要針對陣列或List裡面的字串資料進行排序,需求是先依照字元個數排序,
如果字元個數一樣,再依照字串內容排序,你可以宣告一個像這樣的類別:
public class StringLengthComparator implements Comparator{ @Override public int compare(String s1, String s2) { if (s1.length() != s2.length()) { return s1.length() - s2.length(); } else { return s1.compareTo(s2); } } }
在排序字串的時候,如果需要考慮null值,而且把null值放在最前面,為了可以靈活的應用在其它物件的排序,所以你會套用decorator pattern,宣告一個下面的類別:
public class NullDecoratorComparatorimplements Comparator { private Comparator com; public NullDecoratorComparator(Comparator com) { this.com = com; } @Override public int compare(T s1, T s2) { if (s1 == null || s2 == null) { return s1 == null ? -1 : 1; } return com.compare(s1, s2); } }
設計好需要的類別以後,就可以使用它們為你的資料執行排序的工作:
StringLengthComparator slc = new StringLengthComparator(); Listkws = Arrays.asList( "match", "if", "char", "hash", "assert", "enum", "long"); kws.sort(slc); // if,char,enum,hash,long,match,assert NullDecoratorComparator ndc = new NullDecoratorComparator( slc ); List kws2 = Arrays.asList( "match", "if", "char", "hash", "assert", "enum", "long", null); kws2.sort(ndc); // null,if,char,enum,hash,long,match,assert
上面的作法應該是清楚而且靈活的設計,不過從Java 8開始,你可以使用Lambda的特性,讓這類的設計更加簡化。提供同樣的功能與靈活性,使用Lambda的設計會像這樣:
public static ComparatorgetStringLengthComparator() { return (s1, s2) -> { if (s1.length() != s2.length()) { return s1.length() - s2.length(); } else { return s1.compareTo(s2); } }; } public static Comparator getNullDecoratorComparator(Comparator com) { return (s1, s2) -> { if (s1 == null || s2 == null) { return s1 == null ? -1 : 1; } return com.compare(s1, s2); }; }
不只是設計與維護可以比傳統的作法好一些,使用的時候也更簡單了:
Listkws3 = Arrays.asList( "match", "if", "char", "hash", "assert", "enum", "long"); kws3.sort( getStringLengthComparator() ); // if,char,enum,hash,long,match,assert List kws4 = Arrays.asList( "match", "if", "char", "hash", "assert", "enum", "long", null); kws4.sort( getNullDecoratorComparator( getStringLengthComparator() ) ); // null,if,char,enum,hash,long,match,assert