Stream是什么
Stream是一个数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
集合之于数据,Stream之于计算。
注意点:
- Stream 自己不会存储元素
- Stream 不会改变源对象。相反,它们会返回一个持有结果的新Stream
- Stream 操作是延迟执行的。这意味着它们会等到需要结果的时候才真正执行
Stream 操作的三个步骤
-
1、创建Stream:从一个数据源(数组、集合)中获取一个Stream
创建Stream的几种方式:- 1、可以通过Collection 系列集合提供的stream()/parallelStream()方法
List<String> list = new ArrayList<>(); Stream<String> stream = list.stream();
- 2、通过Arrays中的静态方法stream()获取
User[] users = new User[10]; Stream<User> stream1 = Arrays.stream(users);
- 3、通过Stream类中的静态方法of()获取
Stream<String> stream2 = Stream.of("aa", "bb", "cc");
- 4、创建无限流
//迭代 Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2); //生成 Stream<Double> stream4 = Stream.generate(Math::random);
-
2、中间操作:一个中间操作链,对数据源的数据进行处理
-
筛选与切片
- filter 接收Lambda,从stream中排除某些元素
List<User> users = Arrays.asList( new User(1,"zhangsan", 35, "zhangsan@126.com"), new User(1,"lisi", 56, "lisi@126.com"), new User(1,"wangwu", 45, "wangwu@126.com"), new User(1,"zhaoliu", 22, "zhaoliu@126.com"), new User(1,"sunqi", 27, "sunqi@126.com"), new User(1,"wuba", 67, "wuba@126.com") ); users.stream().filter((user) -> user.getAge() > 50).forEach(System.out::println);
- limit 截断stream,使其元素不超过给定的数量
users.stream().limit(3).forEach(System.out::println);
- skip(n) 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流,与limit互补
users.stream().skip(3).forEach(System.out::println);
- distinct 筛选,通过流所生成元素的hashCode和equals方法去除重复元素
users.stream().distinct().forEach(System.out::println);
-
映射
- map:接收Lambda,将元素转换成其他形式或者提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
List<String> strs = Arrays.asList("aaa","bbb","ccc","ddd"); strs.stream().map((s) -> s.toUpperCase()).forEach(System.out::println); users.stream().map(User::getName).forEach(System.out::println);
- flatmap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连成一个流
public static Stream<Character> filterCharacter(String str){ List<Character> list = new ArrayList<>(); for (char ch : str.toCharArray()) { list.add(ch); } return list.stream(); } //map写法 List<String> strs = Arrays.asList("aaa","bbb","ccc","ddd"); Stream<Stream<Character>> sm = strs.stream().map(MainTest::filterCharacter); sm.forEach((s) -> { s.forEach(System.out::println); }); //flatMap写法 Stream<Character> sm = strs.stream().flatMap(MainTest::filterCharacter); sm.forEach(System.out::println);
-
排序
- sorted() 自然排序
List<String> strs = Arrays.asList("eee", "aaa", "bbb", "ccc", "ddd"); strs.stream().sorted().forEach(System.out::println);
- sorted(Comparator com) 定制排序
users.stream().sorted((u1, u2) -> { if(u1.getAge().equals(u2.getAge())){ return u1.getName().compareTo(u2.getName()); } return u1.getAge().compareTo(u2.getAge()); }).forEach(System.out::println);
-
-
3、终止操作(终端操作):一个终止操作,执行中间操作链,并产生结果
- 查找与匹配
- allMatch 检查是否匹配所有元素
boolean flag = users.stream().allMatch((u) -> u.getAge() > 18); System.out.println(flag);
- anyMatch 检查是否匹配至少一个元素
boolean flag2 = users.stream().anyMatch((u) -> u.getAge() > 66); System.out.println(flag2);
- noneMatch 检查是否没有匹配所有元素
boolean flag3 = users.stream().noneMatch((u) -> u.getAge() > 100); System.out.println(flag3);
- findFirst 返回第一个元素
Optional<User> first = users.stream().findFirst(); System.out.println(first.get());
- findAny 返回当前流中的任意元素
Optional<User> any = users.stream().findAny(); System.out.println(any.get());
- count 返回流中元素的个数
long count = users.stream().count(); System.out.println(count);
- max 返回流中最大的元素
Optional<User> max = users.stream().max((u1, u2) -> u1.getAge().compareTo(u2.getAge())); System.out.println(max.get());
- min 返回流中最小的元素
Optional<User> min = users.stream().min((u1, u2) -> u1.getName().compareTo(u2.getName())); System.out.println(min.get());
- 规约与收集
- 规约
reduce(T identity, BinaryOperator) / reduce(BinaryOperator) 可以将流中元素反复结合起来,得到一个值
我仿佛看到了map-reduceOptional<Integer> reduce = users.stream().map(User::getAge).reduce(Integer::sum); System.out.println(reduce.get()); List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); Integer reduce = list.stream().reduce(0, (x, y) -> x + y); System.out.println(reduce);
- 收集
collect 将流转换为其它形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
List<String> collect = users.stream().map(User::getName).collect(Collectors.toList()); collect.forEach(System.out::println); Set<String> set = users.stream().map(User::getName).collect(Collectors.toSet()); set.forEach(System.out::println); HashSet<String> hashSet = users.stream().map(User::getName).collect(Collectors.toCollection(HashSet::new)); hashSet.forEach(System.out::println); Long collect = users.stream().map(User::getAge).collect(Collectors.counting()); System.out.println(collect); Double collect1 = users.stream().map(User::getAge).collect(Collectors.averagingInt((i) -> i)); System.out.println(collect1); Optional<Integer> collect2 = users.stream().map(User::getAge).collect(Collectors.maxBy(Integer::compare)); System.out.println(collect2.get()); Map<String, List<User>> collect = users.stream().collect(Collectors.groupingBy((u) -> { if (u.getAge() < 30) return "qingnian"; else if (u.getAge() < 60) return "zhongnian"; else return "laonian"; })); collect.forEach((x, y) -> { System.out.println(x + ": " + y ); }); DoubleSummaryStatistics collect = users.stream().collect(Collectors.summarizingDouble(User::getAge)); System.out.println(collect.getMax()); System.out.println(collect.getAverage()); System.out.println(collect.getCount()); System.out.println(collect.getSum()); String collect = users.stream().map(User::getName).collect(Collectors.joining()); System.out.println(collect);
- 规约
Lambda+Stream是不是更加体现了java是世界上最好的语言,哈哈
- 查找与匹配