Stream的创建方式大体为四种
1.Collection.stream()/Collection.parallelSteam();
List<User> userList = Arrays.asList( new User("zs", 23, "bj"), new User("zs1", 23, "bj"), new User("zs3", 23, "bj"), new User("zs4", 23, "bj") ); //创建Stream的第一种方法 集合 Collection.stream()或者Collection.parallelStream(); Stream<User> stream = userList.stream(); Stream<User> userStream = userList.parallelStream();
2.Array.stream()
//创建stream流的第二种方法 数组 Arrays.stream(数组对象); User[] users = userList.toArray(new User[4]); Stream<User> stream1 = Arrays.stream(users);
3.Stream.of(数组对象)
//创建stream流的第三种方法,通过Stream.of()方法 Stream<String> a = Stream.of("a", "b", "c"); Stream<User> users1 = Stream.of(users);
4.Stream.iterate()/Stream.generate()
//创建无限流 //迭代 /* Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 3); iterate.forEach(System.out::println); Stream.iterate(0,x->x+4).limit(20).forEach(System.out::println);*/ //生成 Stream.generate(()->Math.random()).limit(10).forEach(System.out::println); Stream.generate(()->new Random().nextInt(100)).limit(10).forEach(System.out::println);
Stream API的操作分为1.创建 2.中间操作 3.终止操作
上面演示了如何创建Stream,接下里演示如何对Stream进行中间操作。
中间操作先介绍 筛选与切片类 filter(),limit(),skip(),distinct();看起来是不是很像在写sql语句?
@Test public void test02(){ List<User> userList = Arrays.asList( new User("zs", 23, "bj"), new User("zs1", 33, "bj"), new User("zs3", 43, "bj"), new User("zs3", 43, "bj"), new User("zs3", 43, "bj"), new User("zs4", 53, "bj") ); userList.stream() .filter((x)->{ System.out.println("短路了"); return x.getAge() > 30; }) .limit(1) .forEach(System.out::println); System.out.println("----------"); userList.stream().filter((x)->{ return x.getAge() > 20; }).distinct().skip(1).forEach(System.out::println); //userList.stream().map(User::getName).forEach(System.out::println); }
filter()负责过滤Stream中的对象,类似sql中的查询条件
limit()负责决定满足条件的数据中,最后返回几条。写过sql应该能很简单的理解这个概念。
skip()负责决定跳过最前面的几条数据,与limit()相反。
distinct()负责过滤重复的对象,判断重复的条件是对象hashcode()和equals()方法,所以记得重写对象的这两个方法。
接下来介绍Stream中间操作的映射方法,map()、flatMap()、sorted()
map()负责通过重写的方法将Stream中的每一个元素进行转换,对应的方法会作用于每一个被筛选出来的元素。
//map()负责通过重写的方法将Stream中的每一个元素进行转换,对应的方法会作用于每一个被筛选出来的元素 @Test public void test05(){ List<String> stringList = Arrays.asList("aaa","bbb","ccc","ddd","eee"); //将String类型的元素,通过toUpperCase()转换成对应的String类型元素 eg:"aaa"->"AAA"; stringList.stream().map((x)->x.toUpperCase()).forEach(System.out::println); System.out.println("----------"); List<User> userList = Arrays.asList( new User("zs", 23, "bj"), new User("zs1", 33, "bj"), new User("zs3", 43, "bj"), new User("zs4", 53, "bj") ); //将User类型的元素,通过getName()方法转换成String类型的元素。 userList.stream().map(User::getName).forEach(System.out::println); }
flatMap()基本与map()一样,不过flatMap()会将Stream中的所有元素全部整合到一个流中。
@Test public void test05(){ List<String> stringList = Arrays.asList("aaa","bbb","ccc","ddd","eee"); //将String类型的元素,通过toUpperCase()转换成对应的String类型元素 eg:"aaa"->"AAA"; stringList.stream().map((x)->x.toUpperCase()).forEach(System.out::println); System.out.println("----------"); List<User> userList = Arrays.asList( new User("zs", 23, "bj"), new User("zs1", 33, "bj"), new User("zs3", 43, "bj"), new User("zs4", 53, "bj") ); //将User类型的元素,通过getName()方法转换成String类型的元素。 userList.stream().map(User::getName).forEach(System.out::println); System.out.println("-----------"); List<String> stringList2 = Arrays.asList("aaa","bbb","ccc","ddd","eee"); stringList2.stream().map( String2CharacterUtils::string2Character ).forEach(((sm)->sm.forEach(System.out::println))); System.out.println("-----------000----------"); stringList2.stream().flatMap(String2CharacterUtils::string2Character).forEach(System.out::println); }
sorted()负责将元素进行排序,不带参数则按元素的compareTo()进行排序,带参数,则按编写的比较器规则进行排序。
//排序sorted(),参数无比较器则按对象的compareTo()方法排序 //sorted(Comparator<T> comparator) @Test public void sorted(){ List<User> userList = Arrays.asList( new User("zs", 24, "bj"), new User("zs1", 33, "bj"), new User("zs3", 23, "bj"), new User("zs32", 23, "bj"), new User("zs31", 23, "bj"), new User("zs4", 13, "bj") ); userList.stream().sorted().forEach(System.out::println); System.out.println("------------"); userList.stream().sorted( (x,y)->{ if(x.getName().equals(y.getName())){ return x.getAge() - y.getAge(); } return x.getName().compareTo(y.getName()); } ).forEach(System.out::println); }
常用终止操作:
/* 终止操作:查找与匹配 allMatch() 是否匹配所有元素,全匹配返回true,否则返回false anyMatch() 是否匹配至少一个元素,至少匹配一个返回true,否则返回false noneMatch() 是否全部不匹配,满足返回true,否则返回false findFirst() 返回当前流的第一个元素 findAny() 返回当前流的任意元素 count() 计算当前流的总元素个数 max() 返回流中的最大值 min() 返回流中的最小值 * */ @Test public void test06(){ List<User> userList = Arrays.asList( new User("zs", 23, "bj", User.Status.FREE), new User("zs1", 33, "bj", User.Status.BUSY), new User("zs3", 43, "bj",User.Status.VOCATION), new User("zs4", 53, "bj",User.Status.FREE) ); boolean b = userList.stream().allMatch(x -> x.getStatus().equals(User.Status.FREE)); System.out.println("allMatch :" + b); boolean b1 = userList.stream().anyMatch(x -> x.getStatus().equals(User.Status.FREE)); System.out.println("anyMatch:" + b1); System.out.println("----------"); boolean b2 = userList.stream().noneMatch(x -> x.getStatus().equals(User.Status.VOCATION)); System.out.println(b2); Optional<User> first = userList.stream().findFirst(); System.out.println(first.get()); Optional<User> any = userList.parallelStream().findAny(); System.out.println(any.get()); long count = userList.stream().count(); System.out.println(count); Optional<User> max = userList.stream().max((x, y) -> x.getAge() - y.getAge()); System.out.println(max.get()); Optional<User> min = userList.stream().min((x, y) -> x.getAge() - y.getAge()); System.out.println(min.get().getAge()); Optional<Integer> min1 = userList.stream().map(User::getAge).min(Integer::compareTo); System.out.println(min1.get()); } /* * reduce:规约 * reduece(T identity,BinaryOperator)/ reduece(BinaryOperator) 将流中的元素反复结合起来,得到一个值 * */ @Test public void reduce(){ List<Integer> integerList = Arrays.asList(1,2,3,4,5,6,7,8,9);//加起来45 //1.(x=0) + (y=1) = (1) //2.(x=1) + (y=2) = (3) //..... 最终得到45 Integer reduce = integerList.stream().reduce(0, (x, y) -> x + y); System.out.println(reduce);//45 //计算所有员工的年龄 List<User> userList = Arrays.asList( new User("zs", 23, "bj", User.Status.FREE), new User("zs1", 33, "bj", User.Status.BUSY), new User("zs3", 43, "bj",User.Status.VOCATION), new User("zs4", 53, "bj",User.Status.FREE) ); Optional totalAge = userList.stream().map(User::getAge).reduce(Integer::sum); System.out.println(totalAge.get());//152 }
收集操作 collect()
/* * 收集,将流中元素收集为List,Set,Map等集合形式 * */ @Test public void collect(){ List<User> userList = Arrays.asList( new User("zs", 23, "bj", User.Status.FREE), new User("zs1", 33, "bj", User.Status.BUSY), new User("zs3", 43, "bj",User.Status.VOCATION), new User("zs4", 53, "bj",User.Status.FREE), new User("zs4", 53, "bj",User.Status.FREE) ); //将User类型的List集合收集为String类型的List集合 List<String> collect = userList.stream().map(User::getName).collect(Collectors.toList()); collect.forEach(System.out::println); System.out.println("-------------"); //收集为Set集合,去重 Set<String> collect1 = userList.stream().map(User::getName).collect(Collectors.toSet()); collect1.forEach(System.out::println); System.out.println("-----------"); //收集到特定的集合中 HashSet<String> hs = userList.stream().map(User::getName).collect(Collectors.toCollection(HashSet::new)); hs.forEach(System.out::println); //获取流的元素个数 System.out.println("--------------"); Long collect2 = userList.stream().collect(Collectors.counting()); System.out.println(collect2); //获取平均年龄 System.out.println("------"); Double collect3 = userList.stream().collect(Collectors.averagingDouble(User::getAge)); System.out.println(collect3); //获取工资总和 System.out.println("---------"); Integer collect4 = userList.stream().collect(Collectors.summingInt(User::getAge)); System.out.println(collect4); //分组 Map<User.Status, List<User>> collect5 = userList.stream().collect(Collectors.groupingBy(User::getStatus)); System.out.println(collect5); //多级分组 Map<User.Status, Map<Integer, List<User>>> collect6 = userList.stream().collect(Collectors.groupingBy(User::getStatus, Collectors.groupingBy(User::getAge))); System.out.println(collect6); //分区 Map<Boolean, List<User>> collect7 = userList.stream().collect(Collectors.partitioningBy((x) -> x.getAge() > 30)); System.out.println(collect7); //概览 DoubleSummaryStatistics collect8 = userList.stream().collect(Collectors.summarizingDouble(User::getAge)); System.out.println(collect8); //连接 String name = userList.stream().map(User::getName) .collect(Collectors.joining(",")); System.out.println(name); }