1,创建stream流
//1,通过Collection系列集合提供的stream方法 List<String> list = new ArrayList<String>(); Stream<String> stream1 = list.stream(); //2,通过Arrays中提供的静态方法stream 获取数组流 String[] strs = new String[10]; Stream<String> stream2 = Arrays.stream(strs); //3,通过Stream类中的静态方法 of Stream<String> stream3 = Stream.of("c", "s", "s"); //4,创建无限流 //迭代 iterate参数 (从 0 开始 ,每次+2) Stream<Integer> stream4_1 = Stream.iterate(0, x -> x + 2); stream4_1.forEach(System.out::println); //生成 参数使用的是供给型接口,无参,有返回值 下面是返回了一个随机double类型的数值
Stream.generate(() -> Math.random()).forEach(System.out::println);
2,操作流
stream流的操作分为中间操作和终止操作,下面这个操作是从流中过滤大于3的内容
1,filter 接受Lambda,从流中排除某些元素
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8); //中间操作:不会执行任何操作 Stream<Integer> stream = list.stream() .filter(e -> { System.out.println("过滤 中间操作"); return e>3; }); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println);
如果不执行终止操作,中间操作是不会执行的
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!
而在终止操作时一次性全部处理,称为“惰性求值”。
2,limit(n) 截断流,使其元素不超过给定数量
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8); //中间操作:不会执行任何操作 Stream<Integer> stream = list.stream() .filter(e -> { System.out.println("过滤 中间操作"); return e>3; }) .limit(2); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println);
输出结果就是 4 5
3,skip(n) 跳过元素,返回一个扔掉了前n个元素的流,如果流中元素不足n个,则返回一个空流。与limit互补
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8); //中间操作:不会执行任何操作 Stream<Integer> stream = list.stream() .skip(5); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println);
输出结果就是 6 7 8
4,去重操作 distinct
List<Integer> list = Arrays.asList(1,2,3,4,4,4); //中间操作:不会执行任何操作 Stream<Integer> stream = list.stream() .distinct(); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println);
输出结果 1 2 3 4
这里去重是根据对象的hasCode和equals方法,所以如果要对实体类对象执行去重操作,需要重写这两个方法。
5,映射
map 接收Lambda ,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素,上,并将其映射成一个新的元素。
全部转换为大写
List<String> list = Arrays.asList("a","vvv","ddd"); //中间操作:不会执行任何操作 Stream<String> stream = list.stream() .map(x -> x.toUpperCase()); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println); 末尾加s List<String> list = Arrays.asList("a","vvv","ddd"); //中间操作:不会执行任何操作 Stream<String> stream = list.stream() .map(x -> x+"s"); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println);
flatMap 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
接受一个返回值是Stream的方法,把每次返回的流中的数据整合到一个流中。
6,排序
sorted 自然排序 按对象执行的方式进行排序,
List<String> list1 = Arrays.asList("a","vvv","ddd");
//中间操作:不会执行任何操作
Stream<String> stream = list1.stream()
.sorted();
//终止操作:一次性执行全部内容,惰性求值
stream.forEach(System.out::println);
输出结果 a ddd vvv
定制排序 sorted(Comparator c)
这里有个Person类,
public class Person { private Integer age; private double salary; public Person() { } public Person(Integer age, double salary) { this.age = age; this.salary = salary; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } @Override public String toString() { return "Person{" + "age=" + age + ", salary=" + salary + '}'; } }
按年龄排序,如果年龄相同,按工资排序
List<Person> list = Arrays.asList( new Person(18,3939), new Person(38,9999), new Person(19,9988), new Person(38,99) ); //如果只按一个年龄属性排序 list.stream().sorted(Comparator.comparing(Person::getAge)); //按多个字段排序 Stream<Person> stream = list.stream() .sorted((x,y) -> { if(x.getAge() == y.getAge()){ return x.getSalary() > y.getSalary()? 1:-1; } return x.getAge().compareTo(y.getAge()); }); //终止操作:一次性执行全部内容,惰性求值 stream.forEach(System.out::println);
3,终止操作
查找与匹配
List<Person> list = Arrays.asList( new Person(18,3939), new Person(38,9999), new Person(17,9999), new Person(19,9988), new Person(38,99) ); //是否匹配所有元素 此处返回false boolean b = list.stream().allMatch(e -> e.getAge() == 18); System.out.println(b); //至少匹配一个元素,此处返回true boolean b1 = list.stream().anyMatch(e -> e.getAge() == 19); System.out.println(b1); //流中是否没有匹配元素,此处返回false boolean b2 = list.stream().noneMatch(e -> e.getAge() == 19); System.out.println(b2); //排序后获取第一个元素 Optional<Person> first = list.stream().sorted((x, y) -> x.getAge().compareTo(y.getAge())).findFirst(); System.out.println(first); //获取流中任意一个元素 list.stream().findAny(); //返回流中元素的总个数 list.stream().count(); //返回流中最大值 此处根据年龄比较 Optional<Person> max = list.stream().max((x, y) -> x.getAge().compareTo(y.getAge())); System.out.println(max.get()); //返回流中最小值 此处根据年龄比较 Optional<Person> min = list.stream().min((x, y) -> x.getAge().compareTo(y.getAge())); System.out.println(min.get()); //获取最小的年龄 Optional<Integer> age = list.stream().map(Person::getAge).min(Integer::compareTo); System.out.println(age.get()); //获取一个并行流,并行流会使用多个线程操作流,stream()获取的是串行流,单个线程操作流 list.parallelStream();
归约:
List<Integer> intList = Arrays.asList( 1,2,3,4,5,6,7,8,9,10 ); /** * 第一个参数是从几开始,第二个参数是执行的操作 * x=0,y=1 x+y=1 * x=1,y=2 x+y=3 * x=3,y=3 x+y=6 * x=6,y=4 x+y=10 * x=10,y=5 x+y=15 * x=15,y=6 x+y=21 * x=21,y=7 x+y=28 * x=28,y=8 x+y=36 * x=36,y=9 x+y=45 * x=45,y=10 x+y=55 * 输出结果为55 */ Integer reduce = intList.stream().reduce(0, (x, y) -> x + y); System.out.println(reduce); List<Person> list = Arrays.asList( new Person(18,3939), new Person(38,9999), new Person(17,9999), new Person(19,9988), new Person(38,99) ); //取出所有年龄,然后相加 Optional<Integer> reduce1 = list.stream().map(Person::getAge).reduce(Integer::sum); System.out.println(reduce1.get());
收集:
//取出所有年龄放到list集合中 List<Integer> toList = list.stream().map(Person::getAge) .collect(Collectors.toList()); //取出所有年龄放到set集合中 Set<Integer> toSet = list.stream().map(Person::getAge) .collect(Collectors.toSet()); //取出所有年龄放到hashSet集合中 HashSet<Integer> toHashSet = list.stream().map(Person::getAge) .collect(Collectors.toCollection(HashSet::new)); //获取集合中元素总和 Long count = list.stream().collect(Collectors.counting()); //获取年龄平均值 Double avg = list.stream().collect(Collectors.averagingInt(Person::getAge)); //获取工资总和 Double sum = list.stream().collect(Collectors.summingDouble(Person::getSalary)); //获取工资最大值的人 Optional<Person> max = list.stream().collect(Collectors.maxBy((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary()))); System.out.println(max.get()); //获取工资最小值的人 Optional<Person> min = list.stream().collect(Collectors.minBy((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary()))); System.out.println(min.get()); //获取元素个数、总和、最小值、平均值、最大值 DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Person::getSalary)); System.out.println(collect); //输出结果:DoubleSummaryStatistics{count=5, sum=34024.000000, min=99.000000, average=6804.800000, max=9999.000000}
分组和分区
//按年龄分组,年龄相同的是一组 Map<Integer, List<Person>> 分组 = list.stream().collect(Collectors.groupingBy(Person::getAge)); //按年龄分组后按工资分组,多级分组 Map<Integer, Map<String, List<Person>>> 多级分组 = list.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(x -> { return x.getSalary() > 3000 ? "高" : "低"; }))); //分区 满足条件的一个区,不满足条件的一个区 Map<Boolean, List<Person>> collect1 = list.stream().collect(Collectors.partitioningBy(e -> e.getSalary() < 2000));
连接
List<String> strs = Arrays.asList("a","b","cd"); //连接所有内容 String str = strs.stream().collect(Collectors.joining()); System.out.println(str); //输出:abcd //连接所有内容,中间加一个逗号隔开 String str1 = strs.stream().collect(Collectors.joining(",")); System.out.println(str1); //输出:a,b,cd //连接所有内容,中间加一个逗号隔开,两边加上括号 String str2 = strs.stream().collect(Collectors.joining(",","(",")")); System.out.println(str2); //输出:(a,b,cd)