引言
前面小猿总结了下java8中的新特新---Lambda表达式,不熟悉的小伙伴可以查看,这篇文章会用到lambda部分知识
这里小猿将介绍另一大java8引入的语法特性---Stream(流操作)
要知道什么是流式操作(Stream)操作,首先介绍一些什么是流操作,这里通过一个小小的案例看看流操作
//定义一个entity类Person
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
//这里修改返回类型为Person
public Person setName(String name) {
this.name = name;
return this;
}
public int getAge() {
return age;
}
//这里修改返回类型为Person
public Person setAge(int age) {
this.age = age;
return this;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
关键代码
public class Demo {
public static void main(String[] args) {
Person person = new Person();
person.setName("李四").setAge(16);
}
}
通过上面代码我们可以分析当设置完姓名李四之后,我们还能接着设置年龄,这种用上一个过程的结果接着做另一件事的操作就是流操作。也就是说流只是一个计算的过程,并不会存储源对象,下面详细看看流式操作。
Stream实现步骤
1.获取数据源
// 方式一:java8对collection集合的接口扩展,支持创建流
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();// 返回一个顺序流
Stream<String> stream2 = list.parallelStream();// 返回一个并行流
// 方式二:通过Arrays静态方法Stream
Person[] person = new Person[10];
Stream<Person> stream3 = Arrays.stream(person);
// 方式三:通过stream的静态方法.of
Stream<String> stream4 = Stream.of("aa", "bb");
// 方式四:无限流
// 使用iterate创建无限流 0, (x)->x+2中0表示种子,可以查看源码
Stream<Integer> stream5 = Stream.iterate(0, (x) -> x + 2);
// 使用生成创建无限流,使用generate,比如生成随机数流
Stream.generate(()->Math.random());
2.对数据进行处理(过滤 映射)每一步得到一个流,成为中间操作
// 首创建一个集合流
List<Person> persons = Arrays.asList(
new Person("李四", 12),new Person("张三", 15),
new Person("网二", 18),new Person("王哈", 28),new Person("网二", 18));
Stream<Person> pStream = persons.stream();
筛选与切片
主要API
filter(Predicate p) 接收 Lambda , 从流中排除某些元素。
distinct() 筛选,通过流所生成元素的hashCode() 和 equals() 去 除重复元素 (需要重写对象得hashcode和equals方法)
limit(long maxSize) 截断流,使其元素不超过给定数量。
skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素 不足 n 个,则返回一个空流。与 limit(n) 互补
//演示filter(Predicate p)和distinct()API,查询年龄大于15,去重的人的信息
pStream.filter((x) -> x.getAge() > 15)
.distinct()
.forEach(System.out::println);
结果
Person [name=网二, age=18]
Person [name=王哈, age=28]
映射
主要的API
map(Function f) 接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的
DoubleStream。 mapToInt(ToIntFunction f) 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的
IntStream。 mapToLong(ToLongFunction f) 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的
LongStream。 flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流
// 演示map(Function f) 将所有的person年龄+2
pStream.map((p)->p.getAge()+2).forEach(System.out::println);
排序
主要API
sorted() 产生一个新流,其中按自然顺序排序
sorted(Comparator comp) 产生一个新流,其中按比较器顺序排序
//创建一个流
List<String> list = Arrays.asList("aaa","bbb","ccc","dd");
//自然排序
list.stream().sorted().forEach(System.out::println);
// 首创建一个集合流
List<Person> persons = Arrays.asList(
new Person("李四", 12), new Person("张三", 15), new Person("网二", 18),
new Person("王哈", 28), new Person("张二", 18));
persons.stream().sorted((a, b) -> {
if (a.getAge() == b.getAge()) {
return a.getName().compareTo(b.getName());
} else {
return a.getAge() - b.getAge();
}
}).forEach(System.out::println);
3.对流中数据的整合(转成集合 数量),对流中的数据做了整合,称为最终操作
主要API
allMatch(Predicate p) 检查是否匹配所有元素
anyMatch(Predicate p) 检查是否至少匹配一个元素
noneMatch(Predicate p) 检查是否没有匹配所有元素
findFirst() 返回第一个元素
findAny() 返回当前流中的任意元素
// 首创建一个集合流
List<Person> persons = Arrays.asList(
new Person("李四", 12),
new Person("张三", 15),
new Person("网二", 18),
new Person("王哈", 28),
new Person("张二", 18));
//演示取得第一个流
Optional<Person> pOptional = persons.stream().findFirst();
System.out.println(pOptional.get());//Person [name=李四, age=12]