1.遍历/匹配(foreach/find/match)
public static void main(String[] args) {
List<Integer> list = Arrays.asList(5, 8, 9, 4, 7, 3, 1);
list.stream().filter(x -> x > 5).forEach(System.out::println);
Optional<Integer> findFirst = list.stream().filter(x -> x > 5).findFirst();
Optional<Integer> findAny = list.parallelStream().filter(x -> x > 5).findAny();
boolean anyMatch = list.stream().anyMatch(x -> x < 5);
System.out.println("匹配第一个值:" + findFirst.get());
System.out.println("匹配任意一个值:" + findAny.get());
System.out.println("是否存在小于5的值:" + anyMatch);
}
运行结果如下:
8
9
7
匹配第一个值:8
匹配任意一个值:7
是否存在小于5的值:true
2.筛选(filter)
public static void main(String[] args) {
List<Integer> list = Arrays.asList(5, 8, 9, 4, 7, 3, 1);
list.stream().filter(x -> x > 5).forEach(System.out::println);
}
3 聚合(max/min/count)
案例一:获取String集合中最长的元素。
public static void main(String[] args) {
List<String> list = Arrays.asList("abc", "abcd", "abcde", "abcdef", "abcdefg");
Optional<String> max = list.stream().max(Comparator.comparing(String::length));
System.out.println("最长的字符串:" + max.get());
运行结果如下:
最长的字符串:abcdefg
}
案例二:获取Integer集合中的最大值。
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Optional<Integer> max = list.stream().max(Integer::compareTo);
Optional<Integer> max2 = list.stream().max(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
System.out.println("自然排序的最大值:" + max.get());
System.out.println("自定义排序的最大值:" + max2.get());
输出结果:
自然排序的最大值:6 自定义排序的最大值:6
}
案例三:获取员工工资最高的人。
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("a", 8900, 23, "male", "New York"));
personList.add(new Person("b", 7000, 25, "male", "Washington"));
personList.add(new Person("c", 7800, 21, "female", "Washington"));
personList.add(new Person("d", 8200, 24, "female", "New York"));
personList.add(new Person("e", 9500, 25, "male", "New York"));
personList.add(new Person("f", 7900, 26, "female", "New York"));
Optional<Person> max = personList.stream().max(Comparator.comparingInt(Person::getSalary));
System.out.println("员工" +"--" + max.get().getName() + "--的工资最大值:" + max.get().getSalary());
运行结果:
员工--e--的工资最大值:9500
}
案例四:计算Integer集合中大于5的元素的个数。
public static void main(String[] args) {
List<Integer> list = Arrays.asList(7, 6, 4, 8, 2, 11, 9);
long count = list.stream().filter(x -> x > 4).count();
System.out.println("list中大于4的元素个数:" + count);
运行结果:
list中大于4的元素个数:5
}
4 映射(map/flatMap)
映射,将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:
map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
案例一:英文字符串数组的元素全部改为大写
public static void main(String[] args) {
String[] strArr = {"abcd", "bcdd", "defde", "wzh"};
List<String> stringList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
System.out.println("每个元素大写:" + stringList);
}
运行结果:
每个元素大写:[ABCD, BCDD, DEFDE, WZH]
案例二:将两个字符数组合并成一个新的字符数组。
public static void main(String[] args) {
List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
List<String> listNew = list.stream().flatMap(s -> {
String[] split = s.split(",");
Stream<String> s2 = Arrays.stream(split);
return s2;
}).collect(Collectors.toList());
System.out.println("处理前的集合:" + list);
System.out.println("处理后的集合:" + listNew);
}
运行结果:
处理前的集合:[m,k,l,a, 1,3,5,7]
处理后的集合:[m, k, l, a, 1, 3, 5, 7]
5 缩减(reduce)
是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
Optional<Integer> sum = list.stream().reduce(Integer::sum);
Integer sum2 = list.stream().reduce(0, Integer::sum);
Optional<Integer> max = list.stream().reduce(Integer::max);
Integer max2 = list.stream().reduce(0, Integer::max);
Optional<Integer> value = list.stream().reduce((x, y) -> x * y);
System.out.println("求和方式一:" + sum.get());
System.out.println("求和方式二:" + sum2);
System.out.println("求最大值方式一:" + max.get());
System.out.println("求最大值方式二:" + max2);
System.out.println("求乘积:" + value);
运行结果:
求和方式一:28
求和方式二:28
求最大值方式一:7
求最大值方式二:7
求乘积:5040
6 收集(collect)
把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合
案例一: 归集(toList/toSet/toMap)
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 1, 2);
List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
Map<String, String> map = personList.stream().filter(p -> p.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName, Person::getCity));
System.out.println("toList:" + listNew);
System.out.println("toSet:" + set);
System.out.println("toMap:" + map);
运行结果:
toList:[2, 4, 6, 2]
toSet:[2, 4, 6]
toMap:{Tom=New York, Anni=New York}
}
案例二: 统计(count/averaging)
Collectors提供了一系列用于数据统计的静态方法:
计数:size
平均值:averagingInt、averagingLong、averagingDouble
最值:max、min
求和:sum
统计以上所有:summarizingInt、summarizingLong、summarizingDouble
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
long count = personList.size();
Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
Optional<Integer> max = personList.stream().map(Person::getSalary).max(Integer::compare);
int sum = personList.stream().mapToInt(Person::getSalary).sum();
DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println("员工总数:" + count);
System.out.println("员工最高工资:" + max.get());
System.out.println("员工平均工资:" + average);
System.out.println("员工工资总和:" + sum);
System.out.println("员工工资所有统计:" + collect);
}
运行结果:
员工总数:3
员工最高工资:8900
员工平均工资:7900.0
员工工资总和:23700
员工工资所有统计:IntSummaryStatistics{count=3, sum=23700, min=7000, average=7900.000000, max=8900}
案例三: 分组(partitioningBy/groupingBy)
分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
将员工按照工资是否超过8000来分组,分成两个集合
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, "male", "New York"));
personList.add(new Person("Jack", 7000, "male", "Washington"));
personList.add(new Person("Lily", 7800, "female", "Washington"));
personList.add(new Person("Anni", 8200, "female", "New York"));
personList.add(new Person("Owen", 9500, "male", "New York"));
personList.add(new Person("Alisa", 7900, "female", "New York"));
Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getCity)));
System.out.println("员工按性别分组情况:" + group);
System.out.println("员工按性别、地区:" + group2);
}
运行结果:
员工按性别分组情况:{female=[com.ruoyi.web.Test$Person@996db8, com.ruoyi.web.Test$Person@163006a, com.ruoyi.web.Test$Person@1be847c], male=[com.ruoyi.web.Test$Person@1975e01, com.ruoyi.web.Test$Person@2e1f26, com.ruoyi.web.Test$Person@1cf3e99]}
员工按性别、地区:{female={New York=[com.ruoyi.web.Test$Person@163006a, com.ruoyi.web.Test$Person@1be847c], Washington= [com.ruoyi.web.Test$Person@996db8]}, male={New York=[com.ruoyi.web.Test$Person@1975e01, com.ruoyi.web.Test$Person@1cf3e99], Washington=[com.ruoyi.web.Test$Person@2e1f26]}}