终端操作是指:该流已经无法继续使用只能创建一个新的流在继续操作。
中间操作指:后面可以继续进行其他对流的操作。
创建流的方式非常简单
最常见的,你可以通过对集合和数组的转化,创建流。
Listlist=new ArrayList<>(); list.add(1); list.add(2); list.add(3); final Stream stream = list.stream();
你还可以通过切割字符串(返回string数组)创建
String str = "1,2,3,4,54,56,45,5,4"; final Streamstream1 = Arrays.stream(str.split(","));
废话不多说马上就开始实战演练。
这是等会会用到的类,set和get方法可以自己创建或者使用@data注解也行
class Person {
private String name; // 姓名
private int salary; // 薪资
private int age; // 年龄
private String sex; //性别
private String area; // 地区
// 构造方法
public Person(String name, int salary, int age,String sex,String area) {
this.name = name;
this.salary = salary;
this.age = age;
this.sex = sex;
this.area = area;
}}
放在main方法中:
Listfilter和foreach方法。personList = new ArrayList (); personList.add(new Person("Tom", 8900, 23, "male", "New York")); personList.add(new Person("Jack", 7000, 24, "male", "Washington")); personList.add(new Person("Lily", 7800, 34, "female", "Washington")); personList.add(new Person("Anni", 8200, 32, "female", "New York")); personList.add(new Person("Owen", 9500, 25, "male", "New York")); personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
这里使用了lambda表达式,对人员对象的工资进行了过滤,然后foreach循环输出人员的name:
personList.stream().filter(x -> x.getSalary() > 7900) .forEach(x -> System.out.println(x.getName()));
在这里普及一下 : lambda表达式 这里的x代表流中经过的一个元素 ->符号后的就是筛选的条件 filter方法会自动过滤 并只留下符合条件的元素。
findFirst()方法这里同样是筛选
与filter方法不同的地方在于 他会返回第一个符合条件的对象,但是可能为空所以为Optional类型
这里的orElse方法是为了当返回为空是new一个空的对象给他;
Person person1 = personList.parallelStream()
.filter(x -> x.getSalary() > 8000)
.findFirst().orElse(new Person());
System.out.println(person1.getName());
map方法 map方法是最常用且功能最强大的stream方法
map方法可以在方法里面用另一个方法对流中的元素进行映射
这里的.map(Person::getName) 是对元素进行剥离 也就是对元素进行getname方法 取出元素的name 形成一个新的流。
collect(Collectors.toSet()) 是对新的流组成一个集合。
Setcollect = personList .stream().filter(x -> x.getSalary() > 8000) .map(Person::getName) .collect(Collectors.toSet());
map对元素进行方法映射 取出映射后的流 比如 将大写字符转成小写
Listcollect1 = personList.stream() .map(Person::getArea) .map(String::toLowerCase) .collect(Collectors.toList()); System.out.println("collect1 = " + collect1);
这里依然是使用map对流进行映射 将所有元素的工资都加300 不过有一点要注意使用了 map(Person::getSalary) 后 新的流是salary组成的新流
Listcollect2 = personList.stream().map(Person::getSalary) .map(x -> x + 300).collect(Collectors.toList()); System.out.println("collect2 = " + collect2);
我甚至可以这样
StreamTest::personAdd 这种 ::的写法可以调用 非静态方法 应该是因为省略的对象调用的写法
Listcollect3 = personList.stream() .map(StreamTest::personAdd).collect(Collectors.toList());
personAdd方法是我写在main函数外的方法 调用外部函数对stram流中的元素进行映射
public static Person personAdd(Person person) {
person.setSalary(person.getSalary() + 500);
return person;
}
}
你也可以在map中对对象进行重组
Stream
flatmap方法
flatmap方法的作用是将n个流从头到尾串起来 类似为stringbuffer的 append方法
String[] strings = {"a,o,a,q,w,e,e,e", "w,u,u,y,y,t,t,r,r,u"};
Arrays.stream(strings).flatMap(x -> {
Stream stream = Arrays.stream(x.split(","));
return stream;
}).forEach(System.out::println);
max方法
取出流中的元素的最大值
Optionalmax = personList.stream() .map(Person::getAge) .max(Comparator.comparing(Integer::byteValue)); System.out.println("max = " + max);
Optionalmax1 = personList.stream() .max(Comparator.comparingInt(Person::getSalary)); System.out.println("max1.get() = " + max1.get().getSalary());
count方法
将结果集进行聚合 统计条数
long count = personList.stream()
.filter(x -> x.getSalary() > 8000).count();
System.out.println("count = " + count);
reduce方法 :在该方法里同时对流中两个的元素进行重复操作
十分难用
我感觉很鸡肋
规约方法:就是对流里的所有数据进行一个聚合 比如统计 求最大 累乘 啥的
最终缩减成一个值
Integer integer = personList.stream().map(Person::getSalary).reduce((x, y) -> x + y).orElse(-1);
System.out.println(integer);
Integer integer1 = personList.stream().map(Person::getAge).reduce(0, Integer::max);
System.out.println("integer1 = " + integer1);
Integer reduce = personList.stream().reduce(1, (x, p) -> x *= p.getSalary(), Integer::sum);
System.out.println(reduce);
收集(collect)方法
对流中的元素进行各种花式操作
在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。toList、toSet和toMap比较常用,另外还有toCollection、toConcurrentMap等复杂一些的用法。
Collectors提供了一系列用于数据统计的静态方法:
计数:count
平均值:averagingInt、averagingLong、averagingDouble
最值:maxBy、minBy
求和:summingInt、summingLong、summingDouble
统计以上所有:summarizingInt、summarizingLong、summarizingDouble
personList.stream().filter(x -> x.getSalary() > 8000).collect(Collectors.toMap(Person::getName, Person::getSalary)).forEach((s, integer2) -> System.out.println(s + " " + integer2));
Long collect4 = personList.stream().collect(Collectors.counting());
System.out.println("collect4 = " + collect4);
Double collect5 = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
System.out.println("collect5 = " + collect5);
DoubleSummaryStatistics collect6 = personList.stream().collect(Collectors.summarizingDouble(Person::getAge));
System.out.println("collect6 = " + collect6);
Integer collect7 = personList.stream().collect(Collectors.summingInt(Person::getAge));
System.out.println("collect7 = " + collect7);
分组(partitioningBy/groupingBy)
分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
Map> collect8 = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000)); collect8.forEach((x, y) -> { System.out.println(x); for (Person person : y) { System.out.println("person = " + person.getName() + " " + person.getSalary()); } });
Map> collect9 = personList.stream().collect(Collectors.groupingBy(Person::getSex)); collect9.forEach((x, y) -> { System.out.println(x); for (Person person : y) { System.out.println("person = " + person.getName() + " " + person.getSalary()); } });
Map学到这里是不是已经累了,但是我想说不要放弃 就快结束了!!!>> collect10 = personList.stream().collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy(Person::getArea))); collect10.forEach((x, y) -> { System.out.println(x); y.forEach((z, u) -> { System.out.println(z); for (Person p : u) { System.out.println("p.getName()+" "+p.getArea()+" "+p.getArea() = " + p.getName() + " " + p.getArea() + " " + p.getArea()); } }); });
接合(joining)
可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
String collect11 = personList.stream()
.map(Person::getName)
.collect(Collectors.joining("-", "{", "}"));
System.out.println(collect11);
String collect12 = personList.stream().map(x -> {
return String.valueOf(x.getAge());
}).collect(Collectors.joining(",", "{", "}"));
System.out.println(collect12);
sored方法
排序
personList.stream()
.sorted(Comparator.comparingInt(Person::getAge))
.forEach(person -> System.out.println(person.getAge()));
personList.stream().
sorted(Comparator.comparing(Person::getName).thenComparing(Person::getAge))
.forEach(person
-> System.out.println(" name " + person.getName() + " age " + person.getAge()));
最后就是
contcat方法 合并流
limit方法 截取前几位的元素
skip方法 跳过某些元素
String s = "abcdeaaa";
String s1 = "12345112";
Stream stream = Arrays.stream(s.split(""));
Stream stream1 = Arrays.stream(s1.split(""));
String collect13 = Stream.concat(stream, stream1).distinct().collect(Collectors.joining("-", "{", "}"));
System.out.println("collect13 = " + collect13);
Stream.concat(Arrays.stream(s.split("")), Arrays.stream(s1.split(""))).skip(2).limit(6).forEach(System.out::println);



