程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java函數式編程(四):在聚集中查找元素

Java函數式編程(四):在聚集中查找元素

編輯:關於JAVA

Java函數式編程(四):在聚集中查找元素。本站提示廣大學習愛好者:(Java函數式編程(四):在聚集中查找元素)文章只能為提供參考,不一定能成為您想要的結果。以下是Java函數式編程(四):在聚集中查找元素正文


查找元素

如今我們對這個設計優雅的轉化聚集的辦法曾經不生疏了,但它對查找元素卻也是力所不及。不外filter辦法倒是為這個而生的。

我們如今要從一個名字列表中,掏出那些以N開首的名字。固然能夠一個也沒有,成果能夠是個空聚集。我們先用老辦法完成一把。


final List<String> startsWithN = new ArrayList<String>();
for(String name : friends) {
if(name.startsWith("N")) {
startsWithN.add(name);
}
}

這麼簡略的事宜,寫了這麼多代碼,也夠煩瑣的了。我們先創立了一個變量,然後把它初始為一個空聚集。然後遍歷本來的聚集,查找那些以指定字母開首的名字。假如找到,就拔出到聚集裡。

我們用filter辦法來重構一下下面這段代碼,看看它的威力究竟若何。


final List<String> startsWithN =
friends.stream()
.filter(name -> name.startsWith("N"))
.collect(Collectors.toList());

filter辦法吸收一個前往布爾值的lambda表達式。假如表達式成果為true,運轉高低文中的誰人元素就會被添加到成果集中;假如不是,就跳過它。終究前往的是一個Steam,它外面只包括那些表達式前往true的元素。最初我們用一個collect辦法把這個聚集轉化成一個列表——在前面52頁的應用collect辦法和Collecters類中,我們會對這個辦法出來更深刻的商量。

我們來打印一下這個成果集中的元素:

System.out.println(String.format("Found %d names", startsWithN.size()));

從輸入成果很顯著能看出來,這個辦法把聚集中婚配的元素全都找出來了。

Found 2 names

filter辦法和map辦法一樣,也前往了一個迭代器,不外它們也就這點雷同罷了了。map前往的聚集和輸出聚集年夜小是一樣的,而filter前往的可欠好說。它前往的聚集的年夜小區間,從0一向到輸出集的元素個數。和map紛歧樣的是,filter前往的是輸出集的一個子集。

到如今為止,lambda表達式帶來的代碼簡練性讓我們很滿足,不外假如不留意的話,代碼冗余的成績就開端漸漸滋生了。上面我們來評論辯論下這個成績。

lambda表達式的重用

lambda表達式看起來很簡練,現實上一不當心很輕易就湧現代碼冗余了。冗余會招致代碼質量低下,難以保護;假如我們想做一個修改,得把好幾處相干的代碼都一路改失落才行。

防止冗余還可以協助我們晉升機能。相干的代碼都集中在一個處所,如許我們剖析它的機能表示,然後優化這一處的代碼,很輕易就可以晉升代碼的機能。

如今我們來看下為何應用lambda表達式輕易招致代碼冗余,同時斟酌若何去防止它。

final List<String> friends =
Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");
final List<String> editors =
Arrays.asList("Brian", "Jackie", "John", "Mike");
final List<String> comrades =
Arrays.asList("Kate", "Ken", "Nick", "Paula", "Zach");
We want to filter out names that start with a certain letter.

我們願望過濾一下某個字母開首的名字。先用filter辦法簡略地完成一下。

final long countFriendsStartN =
friends.stream()
.filter(name -> name.startsWith("N")).count();
final long countEditorsStartN =
editors.stream()
.filter(name -> name.startsWith("N")).count();
final long countComradesStartN =
comrades.stream()
.filter(name -> name.startsWith("N")).count();

lambda表達式讓代碼看起來很簡練,不外它不知不覺的帶來了代碼的冗余。在下面這個例子中,假如想改一下lambda表達式,我們得改不止一處處所——這可不可。榮幸的是,我們可以把lambda表達式賦值給變量,然後對它們停止重用,就像應用對象一樣。

filter辦法,lambda表達式的吸收方,吸收的是一個java.util.function.Predicate函數式接口的援用。在這裡,Java編譯器又派上用處了,它用指定的lambda表達式生成了Predicate的test辦法的一個完成。如今我們可以更明白的讓Java編譯器去生成這個辦法,而不是在參數界說的處所再生成。在下面例子中,我們可以明白的把lambda表達式存儲到一個Predicate類型的援用外面,然後再把這個援用傳遞給filter辦法;如許做很輕易就防止了代碼冗余。

我們來重構後面這段代碼,讓它相符DRY的准繩吧。(Don't Repeat Yoursef——DRY——准繩,可以參看The Pragmatic Programmer: From Journeyman to Master[HT00],一書)。


final Predicate<String> startsWithN = name -> name.startsWith("N");
final long countFriendsStartN =
friends.stream()
.filter(startsWithN)
.count();
final long countEditorsStartN =
editors.stream()
.filter(startsWithN)
.count();
final long countComradesStartN =
comrades.stream()
.filter(startsWithN)
.count();

如今不消再反復寫誰人lambda表達式了,我們只寫了一次,並把它存儲到了一個叫startsWithN的Predicate類型的援用外面。這前面的三個filter挪用裡,Java編譯器看到在Predicate假裝下的lambda表達式,笑而不語,默默吸收了。

這個新引入的變量為我們清除了代碼冗余。不外不幸的是,前面我們就會看到,仇敵很快又回來報仇雪恥了,我們再看看有甚麼更凶猛的兵器能替我們祛除它們。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved