一.概念理解
Stream可以由數(shù)組或集合創(chuàng)建,對流的操作分為兩種:
- 中間操作,每次返回一個新的流,可以有多個。
- 終端操作,每個流只能進(jìn)行一次終端操作,終端操作結(jié)束后流無法再次使用。終端操作會產(chǎn)生一個新的集合或值。
二、Stream的創(chuàng)建
public class StreamDemo {
public static void main(String[] args) {
// 集合
List<Integer> list = Arrays.asList(1, 2, 3);
// 集合創(chuàng)建一個順序流
Stream<Integer> stream = list.stream();
// 集合創(chuàng)建一個并行流
Stream<Integer> parallelStream = list.parallelStream();
// 數(shù)組
int[] array = {1, 3, 5, 6, 8};
// 數(shù)組創(chuàng)建流方式
IntStream intStream = Arrays.stream(array);
}
}
stream和parallelStream的簡單區(qū)分:?stream是順序流,由主線程按順序?qū)α鲌?zhí)行操作,而parallelStream是并行流,內(nèi)部以多線程并行執(zhí)行的方式對流進(jìn)行操作,但前提是流中的數(shù)據(jù)處理沒有順序要求
三.方法學(xué)習(xí)
1、遍歷/匹配(foreach/find/match)
import java.util.*;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// foreach
list.forEach(System.out::println);
System.out.println("----------");
//find
Optional<Integer> firstData = list.stream().findFirst();
System.out.println(firstData.get());
System.out.println("----------");
//match: anyMatch有一個匹配就返回true noneMatch沒有任何匹配才返回true allMatch所有匹配才返回true
System.out.println(list.stream().anyMatch(x -> x > 4));
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, 3000.0));
employeeList.add(new Employee("李四", 18, 5000.0));
employeeList.add(new Employee("王五", 28, 7000.0));
employeeList.add(new Employee("孫六", 38, 9000.0));
return employeeList;
}
}
執(zhí)行程序返回
1
2
3
4
5
----------
1
----------
true
2、按條件匹配filter?
import java.util.*;
import java.util.stream.Collectors;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> employeeList = initEmployee();
// 篩選年紀(jì)大于18歲的職工
List<Employee> employees = employeeList.stream().filter(s -> s.getAge() > 18).collect(Collectors.toList());
System.out.println(employees);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, 3000.0));
employeeList.add(new Employee("李四", 18, 5000.0));
employeeList.add(new Employee("王五", 28, 7000.0));
employeeList.add(new Employee("孫六", 38, 9000.0));
return employeeList;
}
}
[Employee{name='王五', age=28, salary=7000.0}, Employee{name='孫六', age=38, salary=9000.0}]
3、聚合max、min、count
import java.util.*;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> employeeList = initEmployee();
// 獲取薪水最高的職工
Optional<Employee> employeeOptional = employeeList.stream().max(Comparator.comparing(Employee::getSalary, Double::compareTo));
System.out.println(employeeOptional.get());
// 獲取年級最小的職工
Optional<Employee> employeeOptional1 = employeeList.stream().min(Comparator.comparing(Employee::getAge, Integer::compareTo));
System.out.println(employeeOptional1.get());
// 獲取年級大于18的職工數(shù)量
long count = employeeList.stream().filter(s -> s.getAge() > 18).count();
System.out.println(count);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, 3000.0));
employeeList.add(new Employee("李四", 18, 5000.0));
employeeList.add(new Employee("王五", 28, 7000.0));
employeeList.add(new Employee("孫六", 38, 9000.0));
return employeeList;
}
}
Employee{name='孫六', age=38, salary=9000.0}
Employee{name='張三', age=8, salary=3000.0}
2
4、map與flatMap
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<String> list = Arrays.asList("a","b","c");
// map中把小寫字母轉(zhuǎn)換成大寫
List<String> stringList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
// 輸出[A, B, C]
System.out.println(stringList);
}
}
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
String[] arr = {"z-h-a-n-g", "s-a-n"};
List<String> list = Arrays.asList(arr);
System.out.println(list);
// 將兩個字符數(shù)組合并成一個新的字符數(shù)組
List<String> collect = list.stream().flatMap(x -> {
String[] array = x.split("-");
return Arrays.stream(array);
}).collect(Collectors.toList());
System.out.println(collect);
}
}
[z-h-a-n-g, s-a-n]
[z, h, a, n, g, s, a, n]
5、規(guī)約reduce?
歸約,也稱縮減,顧名思義,是把一個流縮減成一個值,能實(shí)現(xiàn)對集合求和、求乘積和求最值操作。
import java.util.*;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> list = initEmployee();
// 求所有工資的和
Double sum = list.stream().map(Employee::getSalary).reduce(0.0, Double::sum);
System.out.println(sum);
// 求職工工資最大值
Optional<Double> max = list.stream().map(Employee::getSalary).reduce((a, b) -> a > b ? a : b);
System.out.println(max.get());
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, 3000.0));
employeeList.add(new Employee("李四", 18, 5000.0));
employeeList.add(new Employee("王五", 28, 7000.0));
employeeList.add(new Employee("孫六", 38, 9000.0));
return employeeList;
}
}
24000.0
9000.0
6、收集(toList、toSet、toMap)
import java.util.*;
import java.util.stream.Collectors;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> list = initEmployee();
// 返回名字做為key,工資做為value的map數(shù)據(jù)
Map<String, Double> employeeMap = list.stream().collect(Collectors.toMap(Employee::getName, Employee::getSalary));
System.out.println(employeeMap);
// 職工名字集合
List<String> employeeNameList = list.stream().map(Employee::getName).collect(Collectors.toList());
System.out.println(employeeNameList);
// 職工年齡集合
Set<Integer> ageSet = list.stream().map(s -> s.getAge()).collect(Collectors.toSet());
System.out.println(ageSet);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, 3000.0));
employeeList.add(new Employee("李四", 18, 5000.0));
employeeList.add(new Employee("王五", 28, 7000.0));
employeeList.add(new Employee("孫六", 38, 9000.0));
return employeeList;
}
}
{李四=5000.0, 張三=3000.0, 王五=7000.0, 孫六=9000.0}
[張三, 李四, 王五, 孫六]
[18, 38, 8, 28]
7、collect
Collectors提供了一系列用于數(shù)據(jù)統(tǒng)計的靜態(tài)方法:文章來源:http://www.zghlxwxcb.cn/news/detail-471117.html
- 計數(shù):count
- 平均值:averagingInt、averagingLong、averagingDouble
- 最值:maxBy、minBy
- 求和:summingInt、summingLong、summingDouble
- 統(tǒng)計以上所有:summarizingInt、summarizingLong、summarizingDouble
import java.util.*;
import java.util.stream.Collectors;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> employeeList = initEmployee();
// 統(tǒng)計職工人數(shù)
Long count = employeeList.stream().collect(Collectors.counting());
System.out.println(count);
// 獲取職工最高工資
Optional<Double> salaryOptional = employeeList.stream().map(Employee::getSalary).collect(Collectors.maxBy((s1, s2) -> s1.compareTo(s2)));
System.out.println(salaryOptional);
// 獲取職工平均工資
Double averageSalary = employeeList.stream().collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(averageSalary);
//一次性統(tǒng)計職工所有工資信息
DoubleSummaryStatistics summaryStatistics = employeeList.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(summaryStatistics);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, 3000.0));
employeeList.add(new Employee("李四", 18, 5000.0));
employeeList.add(new Employee("王五", 28, 7000.0));
employeeList.add(new Employee("孫六", 38, 9000.0));
return employeeList;
}
}
4
Optional[9000.0]
6000.0
DoubleSummaryStatistics{count=4, sum=24000.000000, min=3000.000000, average=6000.000000, max=9000.000000}
8、分組(partitioningBy/groupingBy)
import java.util.*;
import java.util.stream.Collectors;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> employeeList = initEmployee();
// 將員工按薪資是否高于7000分組
Map<Boolean, List<Employee>> map = employeeList.stream().collect(Collectors.partitioningBy(s -> s.getSalary() > 7000));
System.out.println(map);
// 將職工按性別分組
Map<String, List<Employee>> employeeMap = employeeList.stream().collect(Collectors.groupingBy(Employee::getSex));
System.out.println(employeeMap);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, "男", 3000.0));
employeeList.add(new Employee("李四", 18, "女", 5000.0));
employeeList.add(new Employee("王五", 28, "男", 7000.0));
employeeList.add(new Employee("孫六", 38, "女", 9000.0));
return employeeList;
}
}
{false=[Employee{name='張三', age=8, salary=3000.0}, Employee{name='李四', age=18, salary=5000.0}, Employee{name='王五', age=28, salary=7000.0}], true=[Employee{name='孫六', age=38, salary=9000.0}]}
{女=[Employee{name='李四', age=18, salary=5000.0}, Employee{name='孫六', age=38, salary=9000.0}], 男=[Employee{name='張三', age=8, salary=3000.0}, Employee{name='王五', age=28, salary=7000.0}]}
9、接合joining?
joining可以將stream中的元素用特定的連接符(沒有的話,則直接連接)連接成一個字符串。文章來源地址http://www.zghlxwxcb.cn/news/detail-471117.html
import java.util.*;
import java.util.stream.Collectors;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> employeeList = initEmployee();
// 將職工姓名用逗號拼接返回
String nameData = employeeList.stream().map(Employee::getName).collect(Collectors.joining(","));
System.out.println(nameData);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, "男", 3000.0));
employeeList.add(new Employee("李四", 18, "女", 5000.0));
employeeList.add(new Employee("王五", 28, "男", 7000.0));
employeeList.add(new Employee("孫六", 38, "女", 9000.0));
return employeeList;
}
}
張三,李四,王五,孫六
10、排序sorted
import java.util.*;
import java.util.stream.Collectors;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
List<Employee> employeeList = initEmployee();
// 將職工工資升序排序
List<Employee> employees = employeeList.stream().sorted(Comparator.comparing(Employee::getSalary)).collect(Collectors.toList());
System.out.println(employees);
// 將職工工資降序排序
List<Employee> list = employeeList.stream().sorted(Comparator.comparing(Employee::getSalary).reversed()).collect(Collectors.toList());
System.out.println(list);
}
/**
* 初始化職工列表數(shù)據(jù)
*/
private static List<Employee> initEmployee() {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("張三", 8, "男", 3000.0));
employeeList.add(new Employee("李四", 18, "女", 5000.0));
employeeList.add(new Employee("王五", 28, "男", 7000.0));
employeeList.add(new Employee("孫六", 38, "女", 9000.0));
return employeeList;
}
}
[Employee{name='張三', age=8, salary=3000.0}, Employee{name='李四', age=18, salary=5000.0}, Employee{name='王五', age=28, salary=7000.0}, Employee{name='孫六', age=38, salary=9000.0}]
[Employee{name='孫六', age=38, salary=9000.0}, Employee{name='王五', age=28, salary=7000.0}, Employee{name='李四', age=18, salary=5000.0}, Employee{name='張三', age=8, salary=3000.0}]
11、提取/組合
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author qinxun
* @date 2023-06-02
* @Descripion: 職工測試類
*/
public class EmployeeDemo {
public static void main(String[] args) {
String[] arr1 = {"a", "b", "c", "d"};
String[] arr2 = {"d", "e", "f", "g"};
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
// 合并流
List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
System.out.println(newList);
// 限制從流中獲得前1個數(shù)據(jù)
System.out.println(Stream.of(arr1).limit(1).collect(Collectors.toList()));
// 跳過前2個數(shù)據(jù)
System.out.println(Stream.of(arr1).skip(2).collect(Collectors.toList()));
}
}
[a, b, c, d, e, f, g]
[a]
[c, d]
到了這里,關(guān)于Java8的Stream流的學(xué)習(xí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!