在我们开发中,经常会对集合进行过滤、映射、去重、排序、聚合、统计、遍历、归集、分组、拼接等常用操作,为了写出高效率、干净、简洁的代码,Java 8 API 提供了流 Stream API 来进行处理。
提示:以下是本篇文章正文内容,下面案例可供参考
List<String> list = Arrays.asList("a", "b", "c", "d", "e","", "f");
Stream<String> stream = list.stream(); // 创建一个串行流
Stream<String> parallelStream = list.parallelStream(); // 创建一个并行流
int[] array = {1, 2, 3, 4, 5};
IntStream stream = Arrays.stream(array);
Stream<String> stream = Stream.of("a", "b", "c");
List<String> list = Arrays.asList("a", "b", "c", "d");
List<String> result = list.stream() // 转化为一个流
.filter(line -> !"c".equals(line)) // 排除 "c"
.collect(Collectors.toList()); // 把输出流收集回List中
result.forEach(System.out::println); // 输出 : a, b, d
List<Employee> newList = list.stream().filter(item -> {
return item.getSalary().compareTo(new BigDecimal(10000)) > 0
&& !"项目经理".equals(item.getWorkType());
}).collect(Collectors.toList());
List<String> names = users.stream().map(User::getName).collect(Collectors.toList());
List<String> list1 = Arrays.asList("a", "b", "c", "d");
List<String> upper1 = list1.stream()
.map(String::toUpperCase) // 第一种
.collect(Collectors.toList());
List<String> upper2 = list1.stream()
.map(o -> o.toUpperCase(Locale.ENGLISH)) // 第二种,与第一种一样,第一种是简写
.collect(Collectors.toList());
User u1 = new User(); u1.setAge(1); u1.setName("n1");
User u2 = new User(); u2.setAge(2); u2.setName("n2");
List<User> users = new ArrayList<>(); users.add(u1); users.add(u2);
List<User> collect = users.stream()
.map(o -> { // 这种有返回值的map操作可以使用peek来代替
o.setAge(o.getAge() + 1);
return o; // 将修改的年龄重新赋值,并返回
})
.collect(Collectors.toList());
// 使用peek来代替返回
List<User> collect = users.stream().peek(o -> o.setAge(o.getAge() + 1)).collect(Collectors.toList());
List<String> list = Arrays.asList("a,b,c,d", "1,2,3,4");
List<String> listNew = list.stream().flatMap(s -> {
// 将每个元素转换成一个stream
String[] split = s.split(",");
return Arrays.stream(split);
}).collect(Collectors.toList());
System.out.println(listNew); // [a, b, c, d, 1, 2, 3, 4]
String[] arr1 = { "a", "b", "c", "d" };
String[] arr2 = { "d", "e", "f", "g" };
//创建两个流
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
Stream<String> concatStream = Stream.concat(stream1, stream2);
List<String> collect = list.stream().distinct().collect(Collectors.toList());
System.out.println(list); // [a, b, c, d, d, e, f, g]
System.out.println(collect); // [a, b, c, d, e, f, g]
List<User> newList = users.stream()
.sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList());
List<User> newList2 = users.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
List<User> newList3 = users.stream()
.sorted(Comparator.comparing(User::getAge).thenComparing(User::getSalary))
.collect(Collectors.toList());
List<User> newList4 = users.stream().sorted((p1, p2) -> {
if (p1.getSalary().equals(p2.getSalary())) {
return p2.getAge() - p1.getAge();
} else {
return p2.getSalary() - p1.getSalary();
}
}).collect(Collectors.toList());
List<String> collect = list.stream().limit(2).collect(Collectors.toList());
List<String> collect = list.stream().skip(2).collect(Collectors.toList());
users.forEach(o -> {
o.setSalary(1);
System.out.println(o);
});
IntStream.range(0, list.size())
.forEach(i -> list.get(i).setOrderNum(i));
// 等价于
for (int i = 0; i < list.size(); i++) {
list.get(i).setOrderNum(i);
}
long count = list.stream().map(User::getAge).count();
Optional<User> max = list.stream().max(Comparator.comparing(User::getAge));
Optional<Integer> max = list.stream().map(User::getAge).max(Integer::compare);
Optional<User> max = list.stream().min(Comparator.comparing(User::getAge));
//求和1
Stream<Integer> stream1 = Stream.of(1,2,3,4);
System.out.println("sum:" + stream1.reduce(0, Integer::sum));
//求和2
Stream<Integer> stream2 = Stream.of(1,2,3,4);
Optional<Integer> reduce = stream2.reduce(Integer::sum);
reduce.ifPresent(integer -> System.out.println("sum:" + integer));
//求最大值
Stream<Integer> stream3 = Stream.of(1,2,3,4);
System.out.println("max:" + stream3.reduce(0, (a, b) -> (a >= b ? a : b)));
Stream<Integer> stream1 = Stream.of(1,2,3,4);
System.out.println("result1:" + stream1.allMatch(i -> i > 0)); // 都大于0,true
Stream<Integer> stream2 = Stream.of(1,2,3,4);
System.out.println("result2:" + stream2.anyMatch(i -> i > 3)); // 有一个4大于3,true
Stream<Integer> stream3 = Stream.of(1,2,3,4);
System.out.println("result3:" + stream3.noneMatch(i -> i > 3)); // 只有一个不匹配,false
List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
Map<String, Person> map = list.stream().filter(p -> p.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName, p -> p));
Stream<Integer> stream1 = Stream.of(1,2,3,4);
//获取第一个值
Optional<Integer> first = stream1.findFirst();
System.out.println("first:" + first.get());
Stream<Integer> stream2 = Stream.of(1,2,3,4);
//获取任意一个值, 但是正常情况下一般会取第一个元素,在并行流的情况下会随机取一个元素
Optional<Integer> any = stream2.parallel().findAny();
System.out.println("any:" + any.get());
// 求平均年龄
Double average = list.stream().collect(Collectors.averagingInt(User::getAge));
// 求年龄之和
Integer sum = list.stream().collect(Collectors.summingInt(User::getAge));
// 推荐使用下面这种方式:.mapToInt + sum
Integer sum = list.stream().mapToInt(User::getAge).sum();
List<String> list = Arrays.asList("1","2","3","4");
// 以空字符拼接,输出 1234
String result1 = list.stream().collect(Collectors.joining());
// 以“-”符号拼接,输出 1-2-3-4
String result2 = list.stream().collect(Collectors.joining("-"));
// 传多个参数,输出 [1-2-3-4]
String result= list.stream().collect(Collectors.joining("-", "[", "]"));
Map<String, List<User>> group = list.stream().collect(Collectors.groupingBy(User::getSex));
Map<String, Map<String, List<User>>> group2 = list.stream()
.collect(Collectors.groupingBy(User::getSex, Collectors.groupingBy(User::getArea)));
Map<Boolean, List<User>> part = list.stream()
.collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
场景1:将 user 集合转换成以 id 为 key,以 name 为 value 的 map
注意事项:(k1, k2) -> k2 避免键重复(会报错Duplicate key xxx) k1-取第一个数据;k2-取最后一条数据
其中 item -> item.getName() 如果没有其他操作(比如value为name_age需拼接),可以转化为 User::getName
Map<Integer, String> userMap = userList.stream()
.collect(Collectors.toMap(User::getId, item -> item.getName(), (k1, k2) -> k1));
场景2:将 user 集合转换成以 name_age 为 key,user对象为 value 的 map
key:name_age,value:user对象,其中 item -> item 可以也换为 Function.identity()
Map<String, User> userMap = userList.stream()
.collect(Collectors.toMap(item -> item.getName() + "_" + item.getAge(),
item -> item, (k1, k2) -> k1));
场景3:在map里面构造数据 return什么数据就转成什么类型的list
List<Employee> collect = map.entrySet().stream().map(item -> {
Employee employee = new Employee();
employee.setId(item.getKey());
employee.setEmpName(item.getValue());
return employee;
}).collect(Collectors.toList());
场景4:经常会用到 bigdecimal 进行求值操作
//Bigdecimal求和/极值:
BigDecimal sum = list.stream().map(Employee::getSalary).reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal max = list.stream().map(Employee::getSalary).reduce(BigDecimal.ZERO, BigDecimal::max);
//基本数据类型求和/极值:
Integer sum = list.stream().mapToInt(Employee::getId).sum();
Long sum = list.stream().mapToLong(Employee::getId).sum();
Double sum = list.stream().mapToDouble(Employee::getId).sum();
场景5:对 list 进行去重 或 去重后按指定形式拼接返回
String userName = userList.stream().map(User::getName).distinct().collect(Collectors.joining(","));
List<String> collect = userList.stream().map(User::getName).distinct().collect(Collectors.toList());
// 按多个字段去重
ArrayList<User> collect = userList.stream().collect(Collectors.collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(
Comparator.comparing(p -> p.getName() + "_" + p.getAge()))), ArrayList::new));
场景6:对 list 中数据进行相关统计
IntSummaryStatistics collect = userList.stream().collect(Collectors.summarizingInt(User::getAge));
System.out.println("和:" + collect.getSum());
System.out.println("数量:" + collect.getCount());
System.out.println("最大值:" + collect.getMax());
System.out.println("最小值:" + collect.getMin());
System.out.println("平均值:" + collect.getAverage());
// 平均值
OptionalDouble average = list.stream().mapToInt(Employee::getId).average();
average.getAsDouble();
场景7:计算得到某个薪水的个数,如:5000元的有2个(5000, 2)
Map<Integer, Long> collect = userList.stream()
.collect(Collectors.groupingBy(User::getSalary, Collectors.counting()));
场景8:根据订单号+订单行号分组后进行数据处理
// 按照 age 进行分组
Map<Integer, List<User>> collect = userList.stream().collect(Collectors.groupingBy(User::getAge));
// 按照 age_salary 进行分组
Map<String, List<User>> collect = userList.stream()
.collect(Collectors.groupingBy(o -> o.getAge() + "_" + o.getSalary()));
该有的迟早会有,过分强求也无谓。该失去的,也迟早会失去,正如人生百年,终有一死。倒不如珍惜眼前的平凡生活,享受生活带来的苦乐。