您好,登錄后才能下訂單哦!
這篇文章主要講解了“JDK1.8新特性Stream的功能介紹”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“JDK1.8新特性Stream的功能介紹”吧!
java.util.stream.Collectors
,是從JDK1.8開始新引入的一個(gè)類。從源碼的類注釋上,我們可以知道:<u>Collectors實(shí)現(xiàn)了各種有用歸約的操作,例如類型歸類到新集合、根據(jù)不同標(biāo)準(zhǔn)匯總元素等。</u>透過示例,能讓我們眼前一亮,短短的一行代碼卻能處理如此強(qiáng)大、復(fù)雜的功能:匯總、拼接、累加計(jì)算、分組等。
<u>切記,不要用錯(cuò)哦,是java.util.stream.Collectors
,不是java.util.Collections
。</u>
/** * Implementations of {@link Collector} that implement various useful reduction * operations, such as accumulating elements into collections, summarizing * elements according to various criteria, etc. * * <p>The following are examples of using the predefined collectors to perform * common mutable reduction tasks: * * <pre>{@code * // Accumulate names into a List * List<String> list = people.stream().map(Person::getName).collect(Collectors.toList()); * * // Accumulate names into a TreeSet * Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new)); * * // Convert elements to strings and concatenate them, separated by commas * String joined = things.stream() * .map(Object::toString) * .collect(Collectors.joining(", ")); * * // Compute sum of salaries of employee * int total = employees.stream() * .collect(Collectors.summingInt(Employee::getSalary))); * * // Group employees by department * Map<Department, List<Employee>> byDept * = employees.stream() * .collect(Collectors.groupingBy(Employee::getDepartment)); * * // Compute sum of salaries by department * Map<Department, Integer> totalByDept * = employees.stream() * .collect(Collectors.groupingBy(Employee::getDepartment, * Collectors.summingInt(Employee::getSalary))); * * // Partition students into passing and failing * Map<Boolean, List<Student>> passingFailing = * students.stream() * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD)); * * }</pre> * * @since 1.8 */
換句話說,Collectors結(jié)合Stream將成為集合的終極操作,其中,包括:
類型歸類:將集合中元素按照類型、條件過濾等歸類,存放到指定類型的新集合。
分組:按照條件對(duì)元素進(jìn)行分組,和SQL中group by
的用法有異曲同工之妙。
分區(qū):分組的特殊情況,實(shí)質(zhì)是在做二分組,將符合條件、不符合條件的元素分組到兩個(gè)key
分別為true
和false
的Map
中,從而我們能夠得到符合和不符合的分組新集合。
最值:按照某個(gè)屬性查找最大、最小元素。
累加、匯總:用來完成累加計(jì)算、數(shù)據(jù)匯總(總數(shù)、總和、最小值、最大值、平均值)。
連接:將元素以某種規(guī)則連接起來。
……
將集合中元素按照類型、條件過濾等歸類,存放到指定類型的新集合,List
、Map
、Set
、Collection
或者ConcurrentMap
。涉及以下方法:
Collectors.toList()
Collectors.toMap()
Collectors.toSet()
Collectors.toCollection()
Collectors.toConcurrentMap()
一般都作為終止操作符cololect
的參數(shù)來使用,并伴隨著流的結(jié)束。
常用于收集、篩選出集合(復(fù)雜集合)中的符合條件的數(shù)據(jù),并存放于對(duì)應(yīng)類型的新集合中,便于后續(xù)實(shí)際業(yè)務(wù)邏輯處理。
比如,將名字類型歸類存在到List<String>
集合中:
List<String> list = allPeoples.stream().map(People::getName).collect(Collectors.toList());
按照條件對(duì)元素進(jìn)行分組,和 SQL 中的 group by
用法有異曲同工之妙,通常也建議使用Java代碼進(jìn)行分組處理以減輕數(shù)據(jù)庫(kù)SQL壓力。
分組涉及以下方法:
Collectors.groupingBy(…):普通分組。
Collectors.groupingByConcurrent(…):線程安全的分組。
分組后,返回的是一個(gè)Map
集合,其中key
作為分組對(duì)象,value
作為對(duì)應(yīng)分組結(jié)果。
比如,考慮到People集合中可能會(huì)存在同齡人,將集合按照年齡進(jìn)行分組:
Map<Integer, List<People>> groupingByAge = allPeoples.stream().collect(Collectors.groupingBy(People::getAge));
如果我們不想返回Map
的value
為List
怎么辦?實(shí)際上可以按照下面的方式分組:
Map<Integer, Set<People>> groupingByAge2 = allPeoples.stream().collect(Collectors.groupingBy(People::getAge, Collectors.toSet()));
考慮到同步安全問題時(shí),怎么辦?
采用線程安全的分組Collectors.groupingByConcurrent(…)
,于是:
Map<Integer, List<People>> groupingByAge3 = allPeoples.stream().collect(Collectors.groupingByConcurrent(People::getAge));
是分組的特殊情況,采用Collectors.partitioningBy(…)
方法來完成。
該方法實(shí)質(zhì)是在做二分組,將符合條件、不符合條件的元素分組到兩個(gè)key
分別為true
和false
的Map
中,從而我們能夠得到符合和不符合的分組新集合。
比如,People集合中人名有中文名,也有英文名,將人名按照中、英文名進(jìn)行分區(qū):
Map<Boolean, List<People>> partitioningByName = allPeoples.stream().collect(Collectors.partitioningBy(people -> people.getName().matches("^[a-zA-Z]*"))); // 獲取英文名集合 List<People> englishNames = partitioningByName.get(true); // 獲取中文名集合 List<People> chineseNames = partitioningByName.get(false);
按照某個(gè)屬性查找出最大或最小值元素,并且基于Comparator
接口來對(duì)其進(jìn)行比較,返回一個(gè)Optional對(duì)象,并結(jié)合Optional.isPresent()
判斷并取得最大或最小值。
涉及以下方法:
Collectors.maxBy(…):最大值。
Collectors.minBy(…):最小值。
比如,找到People集合中最大、最小年齡的人:
// 查找最大年齡的人 Optional<People> maxAgeOptional = allPeoples.stream().collect(Collectors.maxBy(Comparator.comparingInt(People::getAge))); People maxAgePeople = null; if (maxAgeOptional.isPresent()) { maxAgePeople = maxAgeOptional.get(); } // 查找最小年齡的人 Optional<People> minAgeOptional = allPeoples.stream().collect(Collectors.minBy(Comparator.comparingInt(People::getAge))); People minAgePeople = null; if (minAgeOptional.isPresent()) { minAgePeople = minAgeOptional.get(); }
用來完成累加計(jì)算、數(shù)據(jù)匯總(總數(shù)、總和、最小值、最大值、平均值)操作。
計(jì)算集合某個(gè)屬性的總和,類似與SQL中的sum
函數(shù)。
涉及以下方法:
Collectors.summingInt/Double/Long(…):按照某個(gè)屬性求和。
Collectors.summarizingInt/Double/Long(…):按照某個(gè)屬性的數(shù)據(jù)進(jìn)行匯總,得到其總數(shù)、總和、最小值、最大值、平均值。
比如,計(jì)算全體人員的薪資總和:
int salaryTotal = allPeoples.stream().collect(Collectors.summingInt(People::getSalary));
如果想要得到全體人員的薪資數(shù)據(jù)整體情況(包括總數(shù)、總和、最小值、最大值、平均值),怎么辦呢?
難道分別要搞多個(gè)Stream流嗎?
當(dāng)然,沒有這么麻煩,只需Collectors.summarizingInt
方法就可輕松搞定。
// 輸出:IntSummaryStatistics{count=10, sum=45000, min=2000, average=4500.000000, max=7000} IntSummaryStatistics intSummaryStatistics = allPeoples.stream().collect(Collectors.summarizingInt(People::getSalary));
將元素以某種規(guī)則連接起來,得到一個(gè)連接字符串。
涉及以下方法:
Collectors.joining():字符串直接連接。
Collectors.joining(CharSequence delimiter):按照字符delimiter
進(jìn)行字符串連接。
Collectors.joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix):按照前綴prefix
,后綴suffix
,并以字符delimiter
進(jìn)行字符串連接。
比如,將People集合中所有名字按照某種連接符進(jìn)行字符串連接:
// 輸出:xcbeyondNikiXiaoMing超哥小白小紅LucyLily超級(jí)飛俠樂迪 String namesStr1 = allPeoples.stream().map(People::getName).collect(Collectors.joining()); // 輸出:xcbeyond,Niki,XiaoMing,超哥,小白,小紅,Lucy,Lily,超級(jí)飛俠,樂迪 String namesStr2 = allPeoples.stream().map(People::getName).collect(Collectors.joining(",")); // 輸出:[xcbeyond,Niki,XiaoMing,超哥,小白,小紅,Lucy,Lily,超級(jí)飛俠,樂迪] String namesStr3 = allPeoples.stream().map(People::getName).collect(Collectors.joining(",", "[", "]"));
本文,只是針對(duì)JDK1.8java.util.stream.Collectors
中最好用的操作進(jìn)行單獨(dú)舉例說明,不涉及嵌套、復(fù)合、疊加使用,實(shí)際業(yè)務(wù)場(chǎng)景下可能會(huì)涉及到多種操作的疊加、組合使用,需按需靈活使用即可。
如果你熟悉了上面這些操作,在面對(duì)復(fù)雜集合、處理復(fù)雜邏輯時(shí),就會(huì)更加得心應(yīng)手。尤其是分組、匯總,簡(jiǎn)直是太好用了。
感謝各位的閱讀,以上就是“JDK1.8新特性Stream的功能介紹”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)JDK1.8新特性Stream的功能介紹這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。