目录
一、流(Stream)
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列
集合讲的是数据,流讲的是计算
注意:
1.Stream 自己不会存储元素
2.Stream 不会改变源对象,相反,他们会返回一个持有结果的新Stream
3.Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行
二、Stream 操作的三个步骤
1、创建Stream
一个数据源(集合、数组),获取一个流
2.中间操作
一个中间操作链,对数据源的数据进行处理
3.终止操作
一个终止操作,执行中间操作链,并产生结果
三、创建Stream
1.可以通过Collection 系列集合提供的stream() 或parallelStream()
List<String> list = new ArrayList<>(); Stream<String> stream = list.stream();
2. 通过Arrays中的静态方法stream()获取数组流
Employee[] emps = new Employee[10]; Stream<Employee> stream = Arrays.stream(emps);
3.通过Stream类中的静态方法of()
Stream<String> stream = Stream.of("aa","bb","cc");
4.创建无限流
(1)迭代
Stream<Integer> stream = Stream.iterate(0,(x) -> x+2); stream.limit(10).forEach(System.out::println);
(2)生成
Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);
四、中间操作
(1)筛选与切片
filter----接口Lambda,从流中排除某些元素
limit-----截断流,使其元素不超过给定数量
skip(n) ----跳过元素,返回一个仍掉了前n个元素的流,若流中元素不足n个,则返回一个空 流,与 limit(n)互补
distinct----筛选,通过流所生成元素的hashCode()和equals() 去除重复元素
filter 例子
List<String> list = Arrays.asList(new Employee("test",12,6666),
new Employee("test1",30,888),
new Employee("test3",18,3333)
new Employee("test4",50,2222));
@Test
public void test1(){
//中间操作:不会执行任何操作
list.stream()
.filter((e) -> e.getAge()>18)
//终止操作:一次性执行全部内容
.forEach(System.out::println);
}
注意:Stream的多个中间操作可以连接形成一个流水线,除非流水线触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,称为“惰性求值”
limit例子
list.stream() .filter((e) -> e.getSalary() > 5000) .limit(2) .forEach(System.out::println);
skip例子
list.stream() .filter((e)-e.getSalary()>5000) .skip(2) .forEach(System.out::println);
distinct 例子
list.stream() .filter((e)-e.getSalary()>5000) .skip(2) .distinct() .forEach(System.out::println);
(2)映射
map----接受Lambda,将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap ----- 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
@Test
public void test5(){
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
list.stream()
.map((str) -> str.toUpperCase())
.forEach(System.out::printLn);
//提取名字
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
}
(3) 排序
sorted() ----自然排序(Comparable)
sorted(Comparator com) ----定制排序
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");
list.stream()
.sorted()
.forEach(System.out::println);
System.out.println("---------------");
employees.stream()
.sorted((e1,e2) -> {
if(e1.getAge().equals(e2.getAge())){
return e1.getName.compareTo(e2.getName());
}else{
return e1.getAge().compareTo(e2.getAge());
}
}).forEach(System.out::println);
五、终止操作
1.查找与匹配
allMatch-----检查是否匹配所有元素
anyMatch-----检查是否至少匹配一个元素
noneMatch-----检查是否没有匹配所有元素
findFirst---------返回第一个元素
findAny --------返回当前流中的任意元素
count ------ 返回流中元素的总个数
max------返回流中最大值
min------返回流中最小值
boolean b1 = employees.stream().allMatch((e) -> e.getStatus.equals(Status.Busy));
Optional<Employee> op = employees.stream() .sorted((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary())) .findFirst(); System.out.println(op.get());
Long count = employees.stream().count();
Optional<Employee> op1 = employees.stream().max((e1,e2) ->Double.compare(e1.getSalary(),e2.getSalary())); System.out.println(op1.get());
Optional<Double> op2 = employees.stream() .map(Employee::getSalary) .min(Double::compare); System.out.println(op2.get());
2.规约
reduce(T identity,BinaryOperator) /reduce(BinaryOperator) -- 可以将流中元素反复结合起来,得到一个值
@Test
public void test3(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream()
.reduce(0,(x,y) -> x+y);
System.out.println(sum);
System.out.println("-----------");
Optional<Double> op = employees.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
System.out.println(op.get());
}
3.收集
collect---将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
@Test
public void test4(){
List<String> list = employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
Set<String> set = employees.stream()
.map(Employees::getName)
.collect(Collectors.toSet());
set.forEach(System.out::println);
HashSet<String> hs = employees.stream()
.map(Employee::getName)
.collect(Collectors.toCollection(HashSet::new));
hs.forEach(System.out::println);
}
//总数
Long count = employees.stream().collect(Collectors.counting());
//平均值
Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
//总和
Double sum = employees.stream() .collect(Collectors.summingDouble(Employee::getSalary));
//最大值
Optional<Employee> max = employees.stream() .collect(Collectors.maxBy((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary()))); System.out.println(max.get());
//最小值
Optional<Employee> min = employees.stream() .map(Employee::getSalary) .collect(Collectors.minBy(Double::compare)); System.out.println(min.get());
//分组
Map<Status,List<Employee>> map= employees.stream() .collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(map);
//多列分组
Map<Status,Map<String,List<Employee>>> map = employees.stream() .collect ( Collectors.groupingBy (Employee::getStatus,Collectors.groupingBy((e) -> { if(((Employee)e).getAge() <=35){ return "青年"; }else{ return "老年"; } } )));
//分区
Map<Boolean,List<Employee>> = employees.stream() .collect(Collectors.partitioningBy((e) -> e.getSalary()>8000));
DoubleSummaryStatustucs dss = employees.stream()
.collect(Collectors.summarizzingDouble(Employee::getSalary));
System.out.println(dss.getSum());
System.out.println(dss.getAverage());
System.out.println(dss.getMax());