一、概述
区别
- Stream关注的是对数据的运算,与CPU打交道
- 集合关注的是数据的存储,与内存打交道
特点
- Stream 自己不会存储元素。
- Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
执行流程
- Stream的实例化
- 一系列的中间操作(过滤、映射、…)
- 终止操作
说明
- 一个中间操作链,对数据源的数据进行处理
- 一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用
二、创建Stream
1.通过集合
List<String>list= Arrays.asList("写轮眼","万花筒","轮回眼","咒印","尾兽","阿修罗","因陀罗");
Stream<String> stream = list.stream();
Stream<String> stringStream = list.parallelStream();
2.通过数组
int []arr=new int[]{1,57,234,897,234};
IntStream stream = Arrays.stream(arr);
Person p1 = new Person("tom",1,0);
Person p2 = new Person("jerry",15,0);
Person[] people = {p1, p2};
Stream<Person> stream1 = Arrays.stream(people);
3.通过Stream的of()
of()参数中的多个元素,可以包含null值,不能存储单个null值
Stream<Integer> integerStream = Stream.of(1, 2, 3, 6, 5, 4, 7, 8, 9);
4.创建无限流
迭代
Stream.iterate(0, new UnaryOperator<Integer>() {
@Override
public Integer apply(Integer integer) {
return integer+2;
}
}).limit(10).forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
生成
Stream<Integer> generate = Stream.generate(new Supplier<Integer>() {
@Override
public Integer get() {
return new Random().nextInt();
}
}).limit(10);
generate.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
三、中间操作
筛选与切片
filter(Predicate p) | 接收Lambda,从流中排除某些元素。 |
---|
limit(n) | 截断流,使其元素不超过给定数量。 |
skip(n) | 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补 |
distinct() | 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 |
takeWhile() | 返回从开头开始的按照指定规则尽量多的元素 |
dropWhile() | 与takeWhile相反,返回剩余的元素。 |
List<Person> person = Person.getMorePerson();
Stream<Person> stream = person.stream();
stream.filter(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getAge()>50;
}
}).forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
System.out.println("-----------------------------------");
person.stream().limit(3).forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
System.out.println("-----------------------------------");
person.stream().skip(3).forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
System.out.println("---------------------------");
person.add(new Person("左倾",0,0));
person.add(new Person("左倾",0,0));
person.add(new Person("左倾",0,0));
person.add(new Person("左倾",0,0));
person.add(new Person("左倾",0,0));
person.stream().distinct().forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
映射
map(Function f) | 接收一个函数作为参数,将元素转换成其他形式或提取信息,该函数会被应用到每个元素上,并将其映射成一个新的元素。 |
---|
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。 |
@Test
public void test2(){
List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
list.stream().map(new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
}).forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("------------------------------------");
Stream<String> stringStream = Person.getMorePerson().stream().map(new Function<Person, String>() {
@Override
public String apply(Person person) {
return person.getName();
}
});
stringStream.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length()>3;
}
}).forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("-------------------------------------");
list.stream().map(new Function<String, Stream<Character>>() {
@Override
public Stream<Character> apply(String s) {
return fromStringToStream(s);
}
}).forEach(new Consumer<Stream<Character>>() {
@Override
public void accept(Stream<Character> characterStream) {
characterStream.forEach(new Consumer<Character>() {
@Override
public void accept(Character character) {
System.out.println(character);
}
});
}
});
System.out.println("-----------------------------");
list.stream().flatMap(new Function<String, Stream<Character>>() {
@Override
public Stream<Character> apply(String s) {
return fromStringToStream(s);
}
}).forEach(new Consumer<Character>() {
@Override
public void accept(Character character) {
System.out.println(character);
}
});
}
public static Stream<Character> fromStringToStream(String string){
ArrayList<Character> list = new ArrayList<>();
for (char c : string.toCharArray()) {
list.add(c);
}
return list.stream();
}
排序
sorted() | 自然排序 |
---|
sorted(Comparator com) | 定制排序–implements Comparator< T> |
List<Integer> list = Arrays.asList(1, 2, 78, 9, 9, 2, 74, 8);
list.stream().sorted().forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
System.out.println("----------------------------------------");
List<Person> person = Person.getMorePerson();
person.stream().sorted(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int age=Integer.compare(o1.getAge(), o2.getAge());
if (age!=0){
return age;
}else {
return o1.getName().compareTo(o2.getName());
}
}
}).forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
四、终止操作
匹配与查找
allMatch(Predicate p) | 检查是否匹配所有元素。练习:是否所有的员工的年龄都大于18 |
---|
anyMatch(Predicate p) | 检查是否至少匹配一个元素。练习:是否存在员工的工资大于100 |
noneMatch(Predicate p) | 检查是否"没有"匹配的元素。练习:是否存在员工姓”雷” |
findFirst | 返回第一个元素 |
findAny | 返回当前流中的任意元素 |
count | 返回流中元素的总个数 |
max(Comparator c) | 返回流中最大值练习:返回最高的工资: |
min(comparator c) | 返回流中最小值 |
forEach(Consumer c) | 内部迭代 |
List<Person> person = Person.getMorePerson();
System.out.println(person.stream().allMatch(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getAge() > 18;
}
}));
System.out.println(person.stream().anyMatch(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getBalance() > 1000;
}
}));
System.out.println(person.stream().noneMatch(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getName().startsWith("雷");
}
}));
System.out.println(person.stream().findFirst());
System.out.println(person.parallelStream().findAny());
List<Person> person = Person.getMorePerson();
System.out.println(person.stream().filter(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getBalance() > 1000;
}
}).count());
Stream<Double> doubleStream = person.stream().map(new Function<Person, Double>() {
@Override
public Double apply(Person person) {
return person.getBalance();
}
});
System.out.println(doubleStream.max(new Comparator<Double>() {
@Override
public int compare(Double o1, Double o2) {
return Double.compare(o1, o2);
}
}));
System.out.println(person.stream().min(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return Double.compare(o1.getBalance(), o2.getBalance());
}
}));
person.forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});
归约
reduce(BinaryOperator) | 可以将流中元素反复结合起来,得到一个值。返回Optional |
---|
reduce(T identity,BinaryOperator accumulator) | 可以将流中元素反复结合起来,得到一个值。返回T |
List<Integer> list = Arrays.asList(1, 5, 789, 12, 987, 123, 498);
System.out.println(list.stream().reduce(0, Integer::sum));
List<Person> person = Person.getMorePerson();
Stream<Double> doubleStream = person.stream().map(new Function<Person, Double>() {
@Override
public Double apply(Person person) {
return person.getBalance();
}
});
System.out.println(doubleStream.reduce(new BinaryOperator<Double>() {
@Override
public Double apply(Double aDouble, Double aDouble2) {
return Double.sum(aDouble, aDouble2);
}
}));
收集
collect(collector c) | 将流转换为其他形式。接收一个 Collector接口的实现, |
---|
List<Person> person = Person.getMorePerson();
List<Person> collect = person.stream().filter(new Predicate<Person>() {
@Override
public boolean test(Person person) {
return person.getBalance() > 5000;
}
}).collect(Collectors.toList());
collect.forEach(new Consumer<Person>() {
@Override
public void accept(Person person) {
System.out.println(person);
}
});