JDK1.8之Stream API
阿新 • • 發佈:2021-01-15
jdk1.8的兩個重大改變,一個是Lambda表示式,另一個就是Stream API。Stream是jdk8中處理集合的關鍵抽象概念,可對集合進行復雜的查詢、過濾、篩選等操作。
流(Stream)的概念
流是資料渠道,用於操作資料來源,所生成一種新的元素序列。集合講的是資料,流講的是計算是操作。
需要注意的是:
- Stream自身不會儲存元素
- Stream不會改變資料來源物件,相反會返回產生一個持有結果的新Stream
- Steam操作是延遲執行的,這意味著他們會等到需要結果的時候才執行。
流的操作步驟
- 建立Stream(獲取一個數據源(集合,陣列),從而獲取一個流)
- 用Stream中間操作(一箇中間操作鏈,用Stream API 對資料來源資料進行操作處理)
- 終止Stream操作(終止操作,執行中間鏈操作,併產生結果)
常見操作程式碼示例
- 示例資料準備
@Data class Student{ private String name; private Integer age; private String gender; public Student() { } public Student(String name, Integer age, String gender) { this.name = name; this.age = age; this.gender = gender; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", gender='" + gender + '\'' + '}'; } } List<Student> stuList = new ArrayList<>(); stuList.add(new Student("張三", 18, "男")); stuList.add(new Student("李四", 28, "女")); stuList.add(new Student("王五", 16, "男")); stuList.add(new Student("趙六", 30, "女")); stuList.add(new Student("孫七", 35, "女")); stuList.add(new Student("周八", 55, "男"));
- 過濾 filter
Stream<Student> stuStream = stuList.stream().filter(i -> i.getAge() > 18);
stuStream.forEach(System.out::println);
// 也可簡寫成
stuList.stream().filter(i -> i.getAge() > 18).forEach(a->{
System.out.println(a.getName());
});
運算結果:
Student{name='李四', age=28, gender='女'} Student{name='趙六', age=30, gender='女'} Student{name='孫七', age=35, gender='女'} Student{name='周八', age=55, gender='男'} 李四 趙六 孫七 周八
- limit 限定集合數量
stuList.stream().filter(i -> i.getAge() > 18).limit(2).forEach(a->{
System.out.println(a.getName());
});
運算結果:
李四
趙六
- skip 跳過元素
skip和limit可一起使用可做分頁效果
stuList.stream().filter(i -> i.getAge() > 18).skip(2).limit(2).forEach(a->{
System.out.println(a.getName());
});
運算結果:
孫七
周八
- distinct 去重
distinct()去重需要重寫實體類的hashCode()和equals()方法這裡僅示例String集合去重
List<String> list2 = new ArrayList<>();
list2.add("中");
list2.add("人");
list2.add("中");
list2.add("去");
list2.stream().distinct().forEach(a->{
System.out.println(a);
});
運算結果:
中
人
去
- 排序 sorted
// 無引數排序
List<String> list2 = new ArrayList<>();
list2.add("e");
list2.add("c");
list2.add("b");
list2.add("z");
list2.stream().sorted().forEach(a->{
System.out.println(a);
});
// 有引數排序
stuList.stream().sorted((o1, o2) -> o2.getAge() - o1.getAge()).forEach(a->{
System.out.println(a.getName());
});
運算結果:
b
c
e
z
周八
孫七
趙六
李四
張三
王五
- count 返回流中個數
long count = stuList.stream().count();
8.max 返回最大值 min 返回最小值
// 按年齡大小正序找最大值
Optional<Student> max = stuList.parallelStream().max((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println(max.get());
// 按年齡大小倒序找最大值
Optional<Student> max1 = stuList.parallelStream().max((o1, o2) -> o2.getAge() - o1.getAge());
System.out.println(max1.get());
// 按年齡大小正序找最小值
Optional<Student> max2 = stuList.parallelStream().min((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println(max2.get());
// 按年齡大小倒序找最小值
Optional<Student> max3 = stuList.parallelStream().min((o1, o2) -> o2.getAge() - o1.getAge());
System.out.println(max3.get());
運算結果:
Student{name='周八', age=55, gender='男'}
Student{name='王五', age=16, gender='男'}
Student{name='王五', age=16, gender='男'}
Student{name='周八', age=55, gender='男'}
- collect 將流轉換為其他形式
List<String> nameList = stuList.stream().map(Student::getName)
.collect(Collectors.toList());
nameList.forEach(System.out::println);
運算結果:
張三
李四
王五
趙六
孫七
周八
Stream API還有其他操作,這裡僅記錄工作中常用API操作。其他操作用到時再做新增。