Stream的特性
1. 不是数据结构,没有内部存储
2. 不支持索引访问
3. 延迟计算
4. 支持并行
5. 很容易生成数组和集合
6. 支持过滤,查找,转换,汇总,聚合等操作
Stream的运行机制
1. 分为源,中间操作,和终止操作
源可以是一个数组,一个集合,一个生成器方法,一个IO通道等
Stream的创建
通过数组创建
String[] str = {"a","b","c","d"};
Stream<String> str1 = Stream.of(str);
str1.forEach(System.out::println);
通过集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
Stream<String> parallelStream = list.parallelStream();
System.out.println(stream.count());
使用Stream的静态方法:of()、iterate()、generate()
Stream<Double> stream = Stream.generate(Math::random).limit(3);
System.out.println(stream.count());
Stream<Integer> streamOf = Stream.of(1, 2, 3, 4, 5, 6);
streamOf.limit(3).map(x -> x*3).forEach(System.out::println);
Stream<Integer> iterate = Stream.iterate(0, x -> x + 3).limit(10);
iterate.forEach(System.out::println);
通过流创建
1. 通过数组
2. 通过集合
3. 通过Stream.generate方法
4. 通过Stream.iterate方法
5. 其他API创建
生成示例
public class Stream_demo {
// 使用数组创建Stream
static void gen1(){
String[] str = {"a","b","c","d"};
Stream<String> str1 = Stream.of(str);
str1.forEach(System.out::println);
}
// 通过集合来创建
static void gen2() {
List<String> list = Arrays.asList("1", "2", "3", "4");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
}
// 通过Stream.generate
static void gen3(){
Stream<Integer> generate = Stream.generate(() -> 1);
// 限制输出10个,否则会无限输出
generate.limit(10).forEach(System.out::println);
}
// 使用iterator
static void gen4(){
Stream<Integer> iterate = Stream.iterate(1, x -> x + 1);
iterate.limit(100).forEach(System.out::println);
}
// 其他方式
static void gen5(){
String string = "hello world";
IntStream chars = string.chars();
chars.forEach(System.out::println);
}
public static void main(String[] args) {
gen5();
}
}
Stream常用Api
终止操作
循环
foeach
计算
min
max
count
average
匹配
anyMatch
allMatch
noneMatch
findFirst
findAny
汇聚
reduce
收集器
toArray
collect
示例
过滤 filter
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
list.stream().filter(x -> (x & 0x1) ==0).forEach(System.out::println);
Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
boolean anyMatch = list.stream().anyMatch(x -> x < 6);
映射 map flatmap
stream.map(x -> {
char[] cs = x.getName().toCharArray();
char before = cs[0];
cs[0] = (before >= 97) && (before <= 122) ? (char) (before -32) : before;
x.setName(String.valueOf(cs));
return x;
}).forEach(System.out::println);
collect算子
List<Integer> collect = list.stream().filter(x -> x > 6).collect(Collectors.toList());
personList.stream().map(p -> p.getName()).collect(Collectors.joining(","))
归集(toList/toSet/toMap)
collect(Collectors.toMap(Person::getName, p -> p))
Map<String, Person> collect = stream.filter(x -> x.getSalary() > 9000).collect(Collectors.toMap(Person::getName, p -> p));
聚合(max/min/count)
max(Comparator.comparing(String::length)
max(Integer::compareTo)
max(
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
max(Comparator.comparingInt(Person::getSalary))
归约 reduce
stream.map(Person::getSalary).reduce(Integer::sum).orElse(100)
统计
Double collect1 = personList.stream().collect(Collectors.averagingLong(Person::getSalary))
Collector<Person, ?, IntSummaryStatistics> ll = Collectors.summarizingInt(Person::getSalary);
IntSummaryStatistics collect2 = personList.stream().collect(ll);
分组(partitioningBy/groupingBy)
Map<Boolean, List<Person>> collect3 = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
Collector<Person, ?, Map<String, List<Person>>> groupby = Collectors.groupingBy(Person::getGender);
Map<String, List<Person>> collect4 = personList.stream().collect(groupby);
排序(sorted)
sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):Comparator排序器自定义排序
List<Person> collect = personList.stream().sorted().collect(Collectors.toList());
List<Person> collect1 = personList.stream().sorted(Comparator.comparingInt(Person::getSalary).reversed()).collect(Collectors.toList());
Person类
package com.chauncy.stream.demo;
import lombok.Data;
@Data
class Person implements Comparable<Person> {
private int id;
private String name;
private int age;
private int salary;
private String gender;
private String address;
public Person() {
}
public Person(int id, String name,int age,int salary, String gender, String address) {
this.id = id;
this.name = name;
this.salary = salary;
this.age = age;
this.gender = gender;
this.address = address;
}
@Override
public int compareTo(Person o) {
return this.getSalary() >= o.getSalary() ? 1 :-1;
}
}
测试
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person(1, "Tom", 28, 3500, "male", "Shanghai"));
personList.add(new Person(2, "Alice", 24, 4300, "female", "Beijing"));
personList.add(new Person(3, "Sharry", 34, 6900, "female","Hangzhou"));
personList.add(new Person(4, "Netty", 29, 12300, "male", "Guangzhou"));
personList.add(new Person(5, "Friday", 27, 9200, "male", "Shenzheng"));
personList.add(new Person(6, "blob", 27, 8760, "male", "Chendou"));
}