Code M In My Time Zone

Java8 使用Function, compose, andThen

2017-08-01

使用 Java 8 的 Predicate,可以先針對特定class設定過濾條件,在stream().filter()時,把Predicate放在filter()中。

而BiFunction, Function是在建立method時,直接依條件把傳入的List參數篩選好再回傳出去。 使用的方式是對BiFunction/Function 用 .apply(arg....) 把要過濾的list 傳入。

測試資料

[Books]

Title PublishDate Author Tags
BookA 20150101 Apple Bee Art, Comics
BookB 20160101 Apple Bee Comics
BookC 20151001 Cake Door Law
BookD 20150601 Egg Frog History
BookE 20161001 Goose Horse Art, Education
BookF 20141001 Ibis Jellyfish Art, Business

建立Publication interface

interface Publication{
	public String getTitle();
	public String getAuthor();
	public List<String> getTags();
	public LocalDate getPublished();
}

建立Book class

class Book implements Publication {
    String title;
    String author;
    List<String> tags;
    LocalDate published;
.
.
//getter, setter....
}

建立BiFunction

建立BiFunction/Function時所用的型別是Publication, 因此在method中, 寫 pubs -> 時,pubs 代表的即是 List, 可由其中直接取出相關欄位來進行條件篩選。

  • 傳入作者名和List,回傳該作者的Publication列表
BiFunction<String, List<Publication>, List<Publication>> getByAuthor = 
(name, pubs) -> pubs.stream()
.filter(a -> a.getAuthor().equals(name)).collect(Collectors.toList());
  • 傳入Tag名稱和List,回傳包含Tag名稱的Publication列表
BiFunction<String, List<Publication>, List<Publication>> getByTag = (tag, pubs) -> pubs.stream()
	  .filter(a -> a.getTags().contains(tag))
	  .collect(Collectors.toList());
  • 傳入List,依日期由近到遠排序後回傳整個列表
Function<List<Publication>, List<Publication>> sortByDate = 
         pubs -> pubs.stream()
			.sorted((x, y) -> y.getPublished()
			.compareTo(x.getPublished()))
			.collect(Collectors.toList());
  • 傳入List,取得第一筆Publication
Function<List<Publication>, Optional<Publication>> getFirst = 
a -> a.stream().findFirst();
  • 傳入List,依日期由近到遠排序後,取得第一筆Publication
Function<List<Publication>, Optional<Publication>> getNewest = 
getFirst.compose(sortByDate);

這邊建立的的Function,是用compose()結合getFirstsortByDate 二個Function。

sortByDate作為compose()的傳入參數,會先執行,然後再執行getFirst。

  • 傳入作者名和List,回傳該作者的最新Publication
BiFunction<String, List<Publication>, Optional<Publication>> newestByAuthor = 
getByAuthor.andThen(getNewest);

這邊建立的的BiFunction,是用andThen()結合getByAuthorgetNewest 二個Function。

使用andThen()時,getByAuthor()先執行,然後再執行getNewest

  • 傳入作者名和List,回傳該作者依日期由近到遠排序的Publication列表
BiFunction<String, List<Publication>, List<Publication>> byAuthorSortedByDate = 
getByAuthor.andThen(sortByDate);
  • 傳入Tag名稱和List,回傳包含Tag名稱依日期由近到遠排序的Publication列表
BiFunction<String, List<Publication>, Optional<Publication>> newestByTag = 
getByTag.andThen(getNewest);

建立測試資料

List<Publication> allBookList = Arrays.asList(
new Book("BookA", "Apple Bee", Arrays.asList("Art", "Comics"), LocalDate.parse("20150101", formatter)),
new Book("BookB", "Apple Bee", Arrays.asList("Comics"), LocalDate.parse("20160101", formatter)),
new Book("BookC", "Cake Door", Arrays.asList("Law"), LocalDate.parse("20151001", formatter)),
new Book("BookD", "Egg Frog", Arrays.asList("History"), LocalDate.parse("20150601", formatter)),
new Book("BookE", "Goose Horse", Arrays.asList("Education", "Art"),
						LocalDate.parse("20161001", formatter)),
new Book("BookF", "Ibis Jellyfish", Arrays.asList("Business","Art"), LocalDate.parse("20141001", formatter)));

進行過濾

System.out.println(" :: getByAuthor (get book by Egg Frog) :: ");
List<Publication> booksByCake = getByAuthor.apply("Egg Frog", allBookList);
booksByCake.forEach( c -> System.out.println(c));

/*
 :: getByAuthor (get book by Egg Frog) :: 
Book [title=BookD, published=2015-06-01, author=Egg Frog, tags=[History]]
*/
System.out.println(" :: getByTag (get books have 'Art' tag) :: ");
List<Publication> booksTagArt = getByTag.apply("Art", allBookList);
booksTagArt.forEach( c -> System.out.println(c));
/*
 :: getByTag (get books have 'Art' tag) :: 
Book [title=BookA, published=2015-01-01, author=Apple Bee, tags=[Art, Comics]]
Book [title=BookE, published=2016-10-01, author=Goose Horse, tags=[Education, Art]]
Book [title=BookF, published=2014-10-01, author=Ibis Jellyfish, tags=[Business, Art]]
*/
System.out.println(" :: sortByDate (sort book by publish date desc):: ");
List<Publication> booksSortedByDate = sortByDate.apply(allBookList);
booksSortedByDate.forEach( c -> System.out.println(c));
/*
 :: sortByDate (sort book by publish date desc):: 
Book [title=BookE, published=2016-10-01, author=Goose Horse, tags=[Education, Art]]
Book [title=BookB, published=2016-01-01, author=Apple Bee, tags=[Comics]]
Book [title=BookC, published=2015-10-01, author=Cake Door, tags=[Law]]
Book [title=BookD, published=2015-06-01, author=Egg Frog, tags=[History]]
Book [title=BookA, published=2015-01-01, author=Apple Bee, tags=[Art, Comics]]
Book [title=BookF, published=2014-10-01, author=Ibis Jellyfish, tags=[Business, Art]]
*/
System.out.println(" :: getFirst (get first book):: ");
Optional<Publication> firstBook = getFirst.apply(allBookList);	System.out.println(firstBook.get().toString());
/*
 :: getFirst (get first book):: 
Book [title=BookA, published=2015-01-01, author=Apple Bee, tags=[Art, Comics]]
*/
System.out.println(" :: getNewest (get newest book):: ");
Optional<Publication> newestBook = getNewest.apply(allBookList)	System.out.println(newestBook.get().toString());
/*
 :: getNewest (get newest book):: 
Book [title=BookE, published=2016-10-01, author=Goose Horse, tags=[Education, Art]]
*/
System.out.println(" :: byAuthorSortedByDate (get books by Apple Bee and order by publish date desc):: ");
List<Publication> booksByAppleBeeSortByDate = byAuthorSortedByDate.apply("Apple Bee", allBookList);
booksByAppleBeeSortByDate.forEach( c -> System.out.println(c));
/*
 :: byAuthorSortedByDate (get books by Apple Bee and order by publish date desc):: 
Book [title=BookB, published=2016-01-01, author=Apple Bee, tags=[Comics]]
Book [title=BookA, published=2015-01-01, author=Apple Bee, tags=[Art, Comics]]
*/
System.out.println(" :: newestByAuthor (get Apple Bee's newest book):: ");
Optional<Publication> newestBookByAppleBee = newestByAuthor.apply("Apple Bee", allBookList);
System.out.println(newestBookByAppleBee.get().toString());
/*
 :: newestByAuthor (get Apple Bee's newest book):: 
Book [title=BookB, published=2016-01-01, author=Apple Bee, tags=[Comics]]
*/
System.out.println(" :: newestByTag (get books have 'Art' tag and order by publish date desc):: ");
Optional<Publication> newestBookTagIsArt = newestByTag.apply("Art", allBookList);
System.out.println(newestBookTagIsArt.get().toString());
/*
 :: newestByTag (get books have 'Art' tag and order by publish date desc):: 
Book [title=BookE, published=2016-10-01, author=Goose Horse, tags=[Education, Art]]
*/

此篇筆記參考 Java 8: Composing functions using compose and andThen

gist:functionComposeAndThen.java


Similar Posts

上一篇 Python basic: IO

Comments

Content