在之前,我們有說到,java8中的stream操作,分爲中間操作和終端操作,在終端操作中,前面也看到了歸約的方式,這篇主要是也說的歸約操作的方式collect,收集器操作,收集器操作,可以當做是一種更高級的歸約操作;
先看下stream中的collect操作
<R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);
第一個,是傳入3個參數的抽象方法,
第二個只有一個參數的先看下stream中的collect操作Collectors靜態工廠類,而在這個靜態工廠類中,大部分的實現,都是調用的三個參數的方法,幾乎滿足了我們日常中所有的操作;所以說,我們只看下,這個靜態工廠類中,有哪些實現;
在java8實戰中,有列舉出來,大家可以自己看下介紹,下面,我們通過代碼,做個演示;
package com.meinergy.vppd.business.api.test;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.junit.Test;
public class TestJava8 {
public static List<Emp> list = new ArrayList<>();
static {
list.add(new Emp("上海", "小名", 17));
list.add(new Emp("北京", "小紅", 18));
list.add(new Emp("深圳", "小藍", 19));
list.add(new Emp("廣州", "小灰", 20));
list.add(new Emp("杭州", "小黃", 21));
list.add(new Emp("貴陽", "小白", 22));
}
@Test
public void test1() {
// 轉list
List<String> names = list.stream().map(emp -> emp.getName()).collect(Collectors.toList());
// 轉set
Set<String> address = list.stream().map(emp -> emp.getName()).collect(Collectors.toSet());
// 轉map,需要指定key和value,Function.identity()表示當前的Emp對象本身
Map<String, Emp> map = list.stream().collect(Collectors.toMap(Emp::getName, Function.identity()));
// 計算元素中的個數
Long count = list.stream().collect(Collectors.counting());
// 數據求和 summingInt summingLong,summingDouble
Integer sumAges = list.stream().collect(Collectors.summingInt(Emp::getAge));
// 平均值 averagingInt,averagingDouble,averagingLong
Double aveAges = list.stream().collect(Collectors.averagingInt(Emp::getAge));
// 綜合處理的,求最大值,最小值,平均值,求和操作
// summarizingInt,summarizingLong,summarizingDouble
IntSummaryStatistics intSummary = list.stream().collect(Collectors.summarizingInt(Emp::getAge));
System.out.println(intSummary.getAverage());// 19.5
System.out.println(intSummary.getMax());// 22
System.out.println(intSummary.getMin());// 17
System.out.println(intSummary.getSum());// 117
// 連接字符串,當然也可以使用重載的方法,加上一些前綴,後綴和中間分隔符
String strEmp = list.stream().map(emp -> emp.getName()).collect(Collectors.joining());
String strEmp1 = list.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中間的分隔符-"));
String strEmp2 = list.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中間的分隔符-", "前綴*", "&後綴"));
System.out.println(strEmp);// 小名小紅小藍小灰小黃小白
// 小名-中間的分隔符-小紅-中間的分隔符-小藍-中間的分隔符-小灰-中間的分隔符-小黃-中間的分隔符-小白
System.out.println(strEmp1);
// 前綴*小名-中間的分隔符-小紅-中間的分隔符-小藍-中間的分隔符-小灰-中間的分隔符-小黃-中間的分隔符-小白&後綴
System.out.println(strEmp2);
// maxBy 按照比較器中的比較結果刷選 最大值
Optional<Integer> maxAge = list.stream().map(emp -> emp.getAge())
.collect(Collectors.maxBy(Comparator.comparing(Function.identity())));
// 最小值
Optional<Integer> minAge = list.stream().map(emp -> emp.getAge())
.collect(Collectors.minBy(Comparator.comparing(Function.identity())));
System.out.println("max:" + maxAge);
System.out.println("min:" + minAge);
// 歸約操作
list.stream().map(emp -> emp.getAge()).collect(Collectors.reducing((x, y) -> x + y));
list.stream().map(emp -> emp.getAge()).collect(Collectors.reducing(0, (x, y) -> x + y));
// 分操作 groupingBy 根據地址,把原list進行分組
Map<String, List<Emp>> mapGroup = list.stream().collect(Collectors.groupingBy(Emp::getAddress));
// partitioningBy 分區操作 需要根據類型指定判斷分區
Map<Boolean, List<Integer>> partitioningMap = list.stream().map(emp -> emp.getAge())
.collect(Collectors.partitioningBy(emp -> emp > 20));
}
static class Emp {
private String address;
private String name;
private Integer age;
public Emp() {
}
public Emp(String address) {
this.address = address;
}
public Emp(String name, Integer age) {
this.name = name;
this.age = age;
}
public Emp(String address, String name, Integer age) {
super();
this.address = address;
this.name = name;
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Emp [address=" + address + ", name=" + name + ", age=" + age + "]";
}
}
}
先介紹在這裏,大家對java8的的函數式接口,以及lambda表達式的寫法,有看不懂的,可以參看我之前的文章
1.lambda表達式
《java8 Lambda表達式簡介》
《java8 lambda表達式,方法的引用以及構造器的引用》
2.函數式接口
《java8 函數式接口簡介》
3.stream接口操作
《JAVA8 Stream接口,map操作,filter操作,flatMap操作》
《JAVA8 stream接口 distinct,sorted,peek,limit,skip》
《java8 stream接口 終端操作 forEachOrdered和forEach》
《java8 stream接口 終端操作 toArray操作》
《java8 stream接口 終端操作 min,max,findFirst,findAny操作》
《java8 stream接口終端操作 count,anyMatch,allMatch,noneMatch》
《java8 stream接口 終端操作 collect操作》
4.其他部分