Stream API 使用一種類似於SQL語句從資料庫查詢數據的直觀方式對Java集合進行運算和表達。 將要處理的元素集合看作一種流, 流在管道中傳輸,我們可以在管道的節點上進行處理, 比如篩選, 排序,聚合等。 Stream的三個操作步驟為: 創建Stream:從一個數據源,如集合、數組中獲取流。 ...
Stream API
使用一種類似於SQL語句從資料庫查詢數據的直觀方式對Java集合進行運算和表達。
將要處理的元素集合看作一種流, 流在管道中傳輸,我們可以在管道的節點上進行處理, 比如篩選, 排序,聚合等。
Stream的三個操作步驟為:
- 創建Stream:從一個數據源,如集合、數組中獲取流。
- 中間操作:對數據源的數據進行操作。
- 終止操作:產生結果。
Stream的操作符大體上分為兩種:中間操作符和終止操作符
1 中間操作符
中間操作符在執行處理程式後,數據流依然可以傳遞給下一級的操作符。
map
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
//接收一個函數作為參數,該函數會被應用到每個元素上,並將其映射成一個新的元素。
public class Person {
public String name;
public int age;
public Person(String name) {
this.name = name;
}
//getter方法
}
//提取對象屬性
Person p1 = new Person("張三");
Person p2 = new Person("李四");
List<Person> personList = new ArrayList<>();
personList.add(p1);
personList.add(p2);
List<String> collect = personList.stream().map(Person::getName).collect(Collectors.toList());
collect.forEach(System.out :: println);
flatmap
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
public class Grade {
private String name;
private List<Student> studentList = new ArrayList<>();
public Grade(String name) {
this.name = name;
}
public void addStudent(Student student) {
studentList.add(student);
}
}
public class Student {
public String name;
public int age;
public Student(String name) {
this.name = name;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Student s1 = new Student("張三");
Student s2 = new Student("李四");
Grade grade1 = new Grade("一班");
grade1.addStudent(s1);
Grade grade2 = new Grade("二班");
grade2.addStudent(s2);
List<Grade> list = new ArrayList<>();
list.add(grade1);
list.add(grade2);
list.stream().flatMap(x -> x.get)
limit
Stream<T> limit(long maxSize);
//設限、截斷
List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 11);
Stream<Integer> stream = list.stream().limit(2);
stream.forEach(System.out :: println);
distinct
Stream<T> distinct();
//去重,通過元素的hashCode()和equals()去除重覆元素
List<Integer> list = Arrays.asList(1, 1, 3, 5, 7, 9, 11);
Stream<Integer> stream3 = list.stream().distinct();
stream3.forEach(System.out :: println);
自定義的實體類使用distinct去重時,一定要先重寫hashCode()和equals()方法
filter
Stream<T> filter(Predicate<? super T> predicate);
//過濾器
List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 11);
Stream<Integer> stream = list.stream().filter(x -> x > 5);
stream.forEach(System.out :: println);
peek
Stream<T> peek(Consumer<? super T> action);
skip
Stream<T> skip(long n);
//跳過,與limit互補,跳過元素返回一個捨棄了前n個元素的流,若流中元素不滿足n個,則返回一個空流
List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 11);
Stream<Integer> stream = list.stream().skip(2);
stream.forEach(System.out :: println);
sorted
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
//排序
list.stream().sorted()
list.stream().sorted(Comparator.reverseOrder())
list.stream().sorted(Comparator.comparing(Student::getAge))
list.stream().sorted(Comparator.comparing(Student::getAge).reversed())
//或者自己實現Comparator邏輯
2 終止操作符
終止操作符就是用來對數據進行收集或者消費的,數據到了終止操作這裡就不會向下流動了,終止操作符只能使用一次。
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);
用 Collectors 來進行 reduction 操作
java.util.stream.Collectors 類的主要作用就是輔助進行各類有用的reduction操作,例如轉變輸出為Collection, 把Stream元素進行歸組等。
count統計操作
long count();
//返迴流中元素的總數
find查找操作
Optional<T> findFirst();
Optional<T> findAny();
//查找
match匹配操作
boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);
Max/Min最值操作
Optional<T> max(Comparator<? super T> comparator);
Optional<T> min(Comparator<? super T> comparator);
reduce規約操作
T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
forEach遍歷操作
void forEach(Consumer<? super T> action);
void forEachOrdered(Consumer<? super T> action);
toArray數組操作
Object[] toArray();
<A> A[] toArray(IntFunction<A[]> generator);
3 流的構建
數組創建
String[] arr = { "a", "b", "c"};
Stream<String> stream1 = Stream.of(arr);
Stream<String> stream2 = Arrays.stream(arr);
Collections創建
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
Stream<String> stream = list.stream();
Stream.generate()
Stream.generate(Math::random).limit(5)
Stream.iterate()
Stream.iterate(0, n -> n + 2).limit(10)