文章目录
前言
Stream流式操作,针对集合、数组、函数、I/O流等提供了映射、转换、过滤、排序、聚合等一系列API,一些原本非常复杂的查询,使用Stream只需要几行代码就可以搞定,大大简化了代码的复杂度。
创建一个流
public void createStream() {
// list构建
Lists.newArrayList(1, 2, 3).stream();
// 数组构建
Arrays.stream(new int[]{1, 2, 3});
// 元素构建
Stream.of(1, 2, 3);
// 元素可以是不同类型的
Stream.of(1, 2, "a");
// 迭代器构建,迭代器构建的是一个无限流,必须要有限制
Stream.iterate(2, item -> item * 2).limit(5);
}
过滤
public void filter() {
// 筛选出不等于“a”的元素
Stream.of(1, 2, "a").filter(item -> !item.equals("a")).forEach(System.out::println);
// 从1-10中筛选出大于5的奇数
IntStream.rangeClosed(1, 10).filter(item -> item % 2 == 1).filter(item -> item > 5).forEach(System.out::println);
}
map转换
public void map() {
// mapToObj
IntStream.rangeClosed(1, 10)
.mapToObj(item -> new Order(item * 2))
.collect(Collectors.toList())
.forEach(System.out::println);
// mapToDouble
double sum = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new Order(item * 2))
.collect(Collectors.toList())
.stream()
.mapToDouble(Order::getAmount)
.sum();
System.out.println(sum);
}
flatMap 先展开再转换
public void flatMap() {
// 构建一个User集合
List<User> userList = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new User("user_" + item,
IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))
.collect(Collectors.toList());
// 遍历其中的Roles集合,看看map和flatMap的区别
userList.stream().map(User::getRoles).forEach(System.out::println);
userList.stream().flatMap(role -> role.getRoles().stream()).forEach(System.out::println);
}
distinct 去重
public void distinct() {
List<User> userList = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new User("user_" + item,
IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))
.collect(Collectors.toList());
// 去重后重新拼接
System.out.println(userList.stream().flatMap(user -> user.getRoles().stream()).map(Role::getRole).distinct().collect(Collectors.joining(",")));
}
sort 排序
public void sort() {
List<Order> orderList = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new Order(item * 2))
.collect(Collectors.toList());
// sort+limit,输出前3大的amount
orderList.stream()
.sorted(Comparator.comparing(Order::getAmount).reversed())
.limit(3)
.collect(Collectors.toList())
.forEach(System.out::println);
}
limit+skip 可实现分页
public void skip() {
List<Order> orderList = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new Order(item * 2))
.collect(Collectors.toList());
// sort+limit+skip
orderList.stream()
.sorted(Comparator.comparing(Order::getAmount).reversed())
.skip(1)
.limit(3)
.collect(Collectors.toList())
.forEach(System.out::println);
}
peek 用于执行结果前后查看,方便调试
public void peek() {
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
}
collect 收集,是流的一种终止操作
public void collect() {
// 拼接字符串
String concat = Stream.of("a", "b", "c").collect(StringBuilder::new, StringBuilder::append,
StringBuilder::append)
.toString();
System.out.println(concat);
// 转成List集合
List<String> asList = Stream.of("a", "b", "c").collect(ArrayList::new, ArrayList::add,
ArrayList::addAll);
System.out.println(asList);
// 分隔符+前后缀
List<User> userList = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new User("user_" + item,
IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role))
.collect(Collectors.toList())))
.collect(Collectors.toList());
System.out.println(
userList.stream()
.flatMap(user -> user.getRoles().stream())
.map(Role::getRole)
.distinct().
collect(Collectors.joining(",", "[", "]")));
List<User> users = IntStream.rangeClosed(1, 10)
.mapToObj(item -> new User("user_" + item,
IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))
.collect(Collectors.toList());
// 转成Map形式
Map<String, List<Role>> collect = users.stream().collect(Collectors.toMap(User::getName, User::getRoles));
collect.entrySet().forEach(System.out::println);
}
grouping 分组
public void grouping() {
List<Person> persons = Lists.newArrayList();
persons.add(new Person("a", "Nanjing", "Jiangsu"));
persons.add(new Person("b", "Nanjing", "Jiangsu"));
persons.add(new Person("c", "WuXi", "Jiangsu"));
persons.add(new Person("d", "WuXi", "Jiangsu"));
persons.add(new Person("e", "Hangzhou", "Zhejiang"));
persons.add(new Person("f", "Hangzhou", "Zhejiang"));
// 先按照省分组,再按照城市分组
Map<String, Map<String, List<Person>>> collect = persons.stream()
.collect(Collectors.groupingBy(Person::getProvince, Collectors.groupingBy(Person::getCity)));
collect.entrySet().forEach(System.out::println);
// 按照省分组,并统计出每个省的数量
persons.stream().collect(Collectors.groupingBy(Person::getProvince, Collectors.counting())).entrySet().forEach(System.out::println);
// 按照省分组,并计算出现次数最多的省
persons.stream().collect(Collectors.groupingBy(Person::getProvince, Collectors.counting())).entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).ifPresent(System.out::println);
}
partitioning 分区
public void partitioning() {
List<Person> persons = Lists.newArrayList();
persons.add(new Person("a", "Nanjing", "Jiangsu"));
persons.add(new Person("b", "Nanjing", "Jiangsu"));
persons.add(new Person("c", "WuXi", "Jiangsu"));
persons.add(new Person("d", "WuXi", "Jiangsu"));
persons.add(new Person("e", "Hangzhou", "Zhejiang"));
persons.add(new Person("f", "Hangzhou", "Zhejiang"));
// 按照城市分组,筛选出城市为“Nanjing”的信息
Stream<Map.Entry<String, List<Person>>> stream = persons.stream().collect(Collectors.groupingBy(Person::getCity)).entrySet().stream();
stream.filter(a -> a.getKey().equals("Nanjing")).forEach(System.out::println);
// 使用partitioningBy的方式,partitioningBy返回的分组只有true和false两种
persons.stream().collect(Collectors.partitioningBy(person -> person.getCity().equals("Nanjing"))).entrySet().stream()
.filter(Map.Entry::getKey).forEach(System.out::println);
}
reduce 使用累计函数进行归约
public void reduce() {
// 累加计算
Integer sum = Stream.of(1, 2, 3, 4, 5).reduce(0, Integer::sum);
System.out.println(sum);
}