Java8 Stream常用API整理(值得收藏)

題 圖:pexels
作 者:程銘程銘你快成名
來 源:https://blog.csdn.net/wangchengming1/article/details/89245402
Java8中有兩大最為重要的改變,第一個是Lambda表達(dá)式,另外一個則是Stream API。
流是 Java8 引入的全新概念,它用來處理集合中的數(shù)據(jù)。
眾所周知,集合操作非常麻煩,若要對集合進(jìn)行篩選、投影,需要寫大量的代碼,而流是以聲明的形式操作集合,它就像 SQL 語句,我們只需告訴流需要對集合進(jìn)行什么操作,它就會自動進(jìn)行操作,并將執(zhí)行結(jié)果交給你,無需我們自己手寫代碼。
在項目中使用 Stream API 可以大大提高效率以及代碼的可讀性,使我們對數(shù)據(jù)進(jìn)行處理的時候事半功倍。
這篇博文以實戰(zhàn)角度出發(fā),講解平時開發(fā)中常用 API 的用法以及一些注意的地方。
首先創(chuàng)建一個對象
public?class?Employee?{
??private?int?id;
??private?String name;
??private?int?age;
??private?double?salary;
??private?Status status;
??public?enum?Status {
????FREE, BUSY, VOCATION;
??}
??public?Employee()?{
??}
??public?Employee(String name)?{
????this.name = name;
??}
??public?Employee(String name, int?age)?{
????this.name = name;
????this.age = age;
??}
??
??public?Employee(int?id, String name, int?age, double?salary)?{
????this.id = id;
????this.name = name;
????this.age = age;
????this.salary = salary;
??}
??public?Employee(int?id, String name, int?age, double?salary, Status status)?{
????this.id = id;
????this.name = name;
????this.age = age;
????this.salary = salary;
????this.status = status;
??}
??//省略get,set等。。。
}
隨便初始化一些數(shù)據(jù)
List
empList = Arrays.asList(new?Employee(102, "李四", 59, 6666.66, Status.BUSY),
??????new?Employee(101, "張三", 18, 9999.99, Status.FREE), new?Employee(103, "王五", 28, 3333.33, Status.VOCATION),
??????new?Employee(104, "趙六", 8, 7777.77, Status.BUSY), new?Employee(104, "趙六", 8, 7777.77, Status.FREE),
??????new?Employee(104, "趙六", 8, 7777.77, Status.FREE), new?Employee(105, "田七", 38, 5555.55, Status.BUSY));
中間操作
根據(jù)條件篩選 filter
/**
* 接收Lambda, 從流中排除某些元素。
*/@Test
void?testFilter()?{
? empList.stream().filter((e) -> {
????return?e.getSalary() >= 5000;
??}).forEach(System.out::println);
}
跳過流的前n個元素 skip
/**
* 跳過元素,返回一個扔掉了前n個元素的流。
*/
@Test
void testSkip() {
??empList.stream().filter((e) -> e.getSalary() >= 5000).skip(2).forEach(System.out::println);
}
去除重復(fù)元素 distinct
/**
* 篩選,通過流所生成元素的 hashCode() 和 equals() 去除重復(fù)元素
*/
@Test
void testDistinct() {
??empList.stream().distinct().forEach(System.out::println);
}
截取流的前n個元素 limit
/**
* 截斷流,使其元素不超過給定數(shù)量。
*/
@Test
void testLimit() {
??empList.stream().filter((e) -> {
????return?e.getSalary() >= 5000;
? }).limit(3).forEach(System.out::println);
}
映射 map
/**
* 接收一個函數(shù)作為參數(shù),該函數(shù)會被應(yīng)用到每個元素上,并將其映射成一個新的元素
*/
@Test
void testMap() {
??empList.stream().map(e -> e.getName()).forEach(System.out::println);
??empList.stream().map(e -> {
????empList.forEach(i -> {
??????i.setName(i.getName() + "111");
????});
????return?e;
??}).collect(Collectors.toList());
}
自然排序 sorted
/**
* 產(chǎn)生一個新流,其中按自然順序排序
*/
@Test
void testSorted() {
??empList.stream().map(Employee::getName).sorted().forEach(System.out::println);
}
自定義排序 sorted(Comparator comp)
/**
* 產(chǎn)生一個新流,其中按自然順序排序
*/
@Test
void testSortedComparator() {
??empList.stream().sorted((x, y) -> {
???if?(x.getAge() == y.getAge()) {
?????return?x.getName().compareTo(y.getName());
? ? } else?{
?????return?Integer.compare(x.getAge(), y.getAge());
???}
??}).forEach(System.out::println);
}
最終操作
是否匹配任一元素 anyMatch
/**
?* 檢查是否至少匹配一個元素
?*/
@Test
void?testAnyMatch() {
??boolean b = empList.stream().anyMatch((e) -> e.getStatus().equals(Status.BUSY));
??System.out.println("boolean is : "?+ b);
}
是否匹配所有元素 allMatch
/**
?* 檢查是否匹配所有元素
?*/
@Test
void?testAllMatch() {
??boolean b = empList.stream().allMatch((e) -> e.getStatus().equals(Status.BUSY));
??System.out.println("boolean is : "?+ b);
}
/**
?* 檢查是否沒有匹配的元素
?*/
@Test
void?testNoneMatch() {
??boolean b = empList.stream().noneMatch((e) -> e.getStatus().equals(Status.BUSY));
??System.out.println("boolean is : "?+ b);
}
返回第一個元素 findFirst
/**
?* 返回第一個元素
?*/
@Test
void?testFindFirst() {
??Optionalop = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
??????.findFirst();
??if?(op.isPresent()) {
????System.out.println("first employee name is : "?+ op.get().getName().toString());
??}
}
/**
?* 返回當(dāng)前流中的任意元素
?*/
@Test
void?testFindAny() {
??Optionalop = empList.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
??????.findAny();
??if?(op.isPresent()) {
????System.out.println("any employee name is : "?+ op.get().getName().toString());
??}
}
返回流的總數(shù) count
/**
?* 返回流中元素的總個數(shù)
?*/
@Test
void?testCount() {
??long?count = empList.stream().filter((e) -> e.getStatus().equals(Status.FREE)).count();
??System.out.println("Count is : "?+ count);
}
返回流中的最大值 max
/**
?* 返回流中最大值
?*/
@Test
void?testMax()?{
??Optionalop = empList.stream().map(Employee::getSalary).max(Double::compare);
??System.out.println(op.get());
}
返回流中的最小值 min
/**
?* 返回流中最小值
?*/
@Test
void?testMin() {
??Optionalop2 = empList.stream().min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
??System.out.println(op2.get());
}
歸約 reduce
歸約是將集合中的所有元素經(jīng)過指定運算,折疊成一個元素輸出
/**
?* 可以將流中元素反復(fù)結(jié)合起來,得到一個值。返回T
?*/
@Test
void?testReduce()?{
??Optionalop = empList.stream().map(Employee::getSalary).reduce(Double::sum);
??System.out.println(op.get());
}
/**
?* 可以將流中元素反復(fù)結(jié)合起來,得到一個值,返回Optional< T>
?*/
@Test
void?testReduce1()?{
??Optionalsum = empList.stream().map(Employee::getName).flatMap(Java8Stream::filterCharacter)
??????.map((ch) -> {
????????if?(ch.equals('六'))
??????????return?1;
????????else
??????????return?0;
??????}).reduce(Integer::sum);
??System.out.println(sum.get());
}
將元素收集到 list 里 Collectors.toList()
/**
?* 把流中的元素收集到list里。
?*/
@Test
void testCollectorsToList() {
??Listlist?= empList.stream().map(Employee::getName).collect(Collectors.toList());
??list.forEach(System.out::println);
}
將元素收集到 set 里 Collectors.toSet()
/**
?* 把流中的元素收集到set里。
?*/
@Test
void testCollectorsToSet() {
??Setlist?= empList.stream().map(Employee::getName).collect(Collectors.toSet());
??list.forEach(System.out::println);
}
把流中的元素收集到新創(chuàng)建的集合里?Collectors.toCollection(HashSet::new)
/**
?* 把流中的元素收集到新創(chuàng)建的集合里。
?*/
@Test
void testCollectorsToCollection() {
??HashSeths = empList.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
??hs.forEach(System.out::println);
}
根據(jù)比較器選擇最大值 Collectors.maxBy()
/**
?* 根據(jù)比較器選擇最大值。
?*/
@Test
void?testCollectorsMaxBy()?{
??Optionalmax = empList.stream().map(Employee::getSalary).collect(Collectors.maxBy(Double::compare));
??System.out.println(max.get());
}
根據(jù)比較器選擇最小值 Collectors.minBy()
/**
?* 根據(jù)比較器選擇最小值。
?*/
@Test
void?testCollectorsMinBy()?{
??Optionalmax = empList.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
??System.out.println(max.get());
}
對流中元素的某個字段求和 Collectors.summingDouble()
/**
?* 對流中元素的整數(shù)屬性求和。
?*/
@Test
void?testCollectorsSummingDouble()?{
??Double sum = empList.stream().collect(Collectors.summingDouble(Employee::getSalary));
??System.out.println(sum);
}
對流中元素的某個字段求平均值 Collectors.averagingDouble()
/**
?* 計算流中元素Integer屬性的平均值。
?*/
@Test
void?testCollectorsAveragingDouble()?{
??Double avg = empList.stream().collect(Collectors.averagingDouble(Employee::getSalary));
??System.out.println(avg);
}
分組,類似sql的 group by?Collectors.groupingBy
/**
?* 分組
?*/
@Test
void?testCollectorsGroupingBy()?{
??Map> map?= empList.stream().collect(Collectors.groupingBy(Employee::getStatus));
??System.out.println(map);
}
/**
?* 多級分組
?*/
@Test
void?testCollectorsGroupingBy1()?{
??Map>> map?= empList.stream()
??????.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
????????if?(e.getAge() >= 60)
??????????return?"老年";
????????else?if?(e.getAge() >= 35)
??????????return?"中年";
????????else
??????????return?"成年";
??????})));
??System.out.println(map);
}
字符串拼接 Collectors.joining()
/**
?* 字符串拼接
?*/
@Test
void?testCollectorsJoining()?{
??String str = empList.stream().map(Employee::getName).collect(Collectors.joining(",", "----", "----"));
??System.out.println(str);
}
public?static?Stream
filterCharacter(String str) {
??Listlist?= new?ArrayList<>();
??for?(Character ch : str.toCharArray()) {
????list.add(ch);
??}
??return?list.stream();
}


下載方式
1.?首先掃描下方二維碼
2.?后臺回復(fù)「555」即可獲取
注明:僅僅作為知識分享,切勿用于其它商業(yè)活動 。感謝所有技術(shù)分享者的付出。
點贊是最大的支持?
