文章目录
Stream是什么?
Stream API (java.util.stream)把真正的函数式编程风格引入到Java中,这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效、干净、简洁的代码、
Stream是Java8中处理集合的关键抽象概念,它可以指定你对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来执行操作。简言之,Stream API提供了一种高效且易于使用的处理数据的方式。
是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列。
“集合讲的是数据,Stream讲的是计算!”
注意
- Stream自己不会存储元素。
- Stream不会改变该源对象,相反,他们会返回一个持有结果的新Stream。
- Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。
如何操作Stream
三个步骤:
- 创建Stream (四种方法) 常用前两个
import ming.lambda.Cat;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* 1. Stream 关注的是对数据的运算,与CPU打交道
* 集合关注的是数据存储,与内存打交道
*
* 2. Stream 自己不会存储元素,
* Stream 不会改变源对象,相反他们会返回一个持有结果的新Stream
* Stream 操作是延迟执行的,(因为在终止操作才执行)
*
* 3. 流程
* Stream实例化 --> 一系列中间操作 --> 终止操作
*
*/
public class StreamDemo1 {
// Stream实例化
// 一、通过集合
@Test
public void test1(){
//1. 利用List的stream() : 返回一个顺序流
List<Cat> catList = CatData.getCatList();
Stream<Cat> stream = catList.stream();
//2. List中的parallelStream() : 返回一个并行流
Stream<Cat> stream1 = catList.parallelStream();
}
// 二、 通过数组
@Test
public void test2(){
//1. 利用Arrays类的static Stream<T> stream(T[] array): 返回一个流
int[] arr=new int[]{1,2,3,4,5,6};
IntStream stream = Arrays.stream(arr);
Cat cat1 = new Cat();
Cat cat2 = new Cat();
Cat[] cats = new Cat[]{cat1,cat2};
Stream<Cat> stream1 = Arrays.stream(cats);
}
// 三、Stream的of()
@Test
public void test3(){
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
}
// 四、创建无限流 (用于造数据)
@Test
public void test4(){
//迭代 public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f){}
//遍历前10个偶数
Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);
//生成 public static<T> Stream<T> generate(Supplier<T> s){}
//遍历生成前10个随机数
Stream.generate(Math::random).limit(10).forEach(System.out::println);
}
}
- 中间操作
三种类型
(1)筛选与切片
(2)映射
(3)排序
前期准备
import ming.lambda.Cat; //自己定义Cat实体类
import java.util.ArrayList;
import java.util.List;
/**
* @Author: mei_ming
* @DateTime: 2022/6/3 16:30
* @Description: 测试数据源
*/
public class CatData {
public static List<Cat> getCatList(){
List<Cat> cats = new ArrayList<>();
cats.add(new Cat( "cat1", 1, "bule", 1400));
cats.add(new Cat( "cat2", 2, "red", 1500));
cats.add(new Cat( "cat3", 3, "yellow", 4000));
cats.add(new Cat( "cat4", 4, "bule", 2000));
cats.add(new Cat( "cat5", 1, "bule", 2500));
cats.add(new Cat( "cat6", 2, "bule", 1600));
cats.add(new Cat( "cat10", 3, "orange", 2100));
cats.add(new Cat( "cat11", 4, "bule", 1900));
return cats;
}
}
import ming.lambda.Cat;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
/**
* @Author: mei_ming
* @DateTime: 2022/6/3 16:54
* @Description: Stream的中间操作
*/
public class StreamDemo2 {
// Stream的中间操作
//1.筛选与切片
@Test
public void test1(){
List<Cat> list = CatData.getCatList();
//filter : Stream<T> filter(Predicate<? super T> predicate) --接收lambda,从流中排除某些元素
//查找小猫价格大于2000的猫
Stream<Cat> stream = list.stream();
stream.filter(cat -> cat.getPrice()>2000).forEach(System.out::println);
System.out.println();
//limit(n) -截断流,使其元素不超过给定的数量
list.stream().limit(3).forEach(System.out::println);
System.out.println();
//skip(n) -跳过元素
list.stream().skip(3).forEach(System.out::println);
System.out.println();
//distinct --筛选
list.add(new Cat("cat9",1,"bule",2000));
list.add(new Cat("cat9",1,"bule",2000));
list.add(new Cat("cat9",1,"bule",2000));
list.add(new Cat("cat9",1,"bule",2000));
// System.out.println(list); //出现重复元素
// list.stream().distinct().forEach(System.out::println); //需要重写hashcode与equals
}
//2.映射
@Test
public void test2(){
//1. <R> Stream<R> map(Function<? super T, ? extends R> mapper); 映射 相当于add()
List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
list.stream().map(str->str.toUpperCase()).forEach(System.out::println);
System.out.println();
//获取Cat name名字长度大于4的Cat名字
List<Cat> list1 = CatData.getCatList();
Stream<String> nameStream = list1.stream().map(Cat::getName);
nameStream.filter(name->name.length()>4).forEach(System.out::println); //cat10,cat11
System.out.println();
//练习2: 遍历每个元素
Stream<Stream<Character>> streamStream = list.stream().map(StreamDemo2::fromStringTOStream);
streamStream.forEach(s->{
s.forEach(System.out::println);
});
System.out.println();
//2. <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); 相当于addAll()
//利用flatMap 简化 练习2 遍历每个元素
list.stream().flatMap(StreamDemo2::fromStringTOStream).forEach(System.out::println);
}
//将字符串中的多个字符构成的集合转换成对应的Stream的实例
public static Stream<Character> fromStringTOStream(String str){
ArrayList<Character> list = new ArrayList<>();
for (Character c:str.toCharArray()) {
list.add(c);
}
return list.stream();
}
@Test
public void test3(){
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
ArrayList list1 = new ArrayList();
list1.add(4);
list1.add(5);
list1.add(6);
// list.add(list1); // [1, 2, 3, [4, 5, 6]]
list.addAll(list1); // [1, 2, 3, 4, 5, 6]
System.out.println(list);
}
// 3.排序
@Test
public void test4(){
//1.sorted() --自然排序
List<Integer> list = Arrays.asList(12, 59, 0, -20, 10, 30);
list.stream().sorted().forEach(System.out::println);
//抛出异常 ClassCastException: ming.lambda.Cat cannot be cast to java.lang.Comparable
// List<Cat> list1 = CatData.getCatList();
// list1.stream().sorted().forEach(System.out::println);
System.out.println();
//2. sorted(Comparator com) --定制排序
List<Cat> list1 = CatData.getCatList();
list1.stream().sorted((cat1,cat2)->{
return Integer.compare(cat1.getAge(),cat2.getAge());
}).forEach(System.out::println);
}
}
- 终止操作
三种类型
(1)匹配与查找
(2)规约
(3)收集
import ming.lambda.Cat;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Author: mei_ming
* @DateTime: 2022/6/3 17:50
* @Description: Stream的终止操作
*
*/
public class StreamDemo3 {
//1. 匹配与查找
@Test
public void test1(){
List<Cat> catList = CatData.getCatList();
//allMatch() :boolean allMatch(Predicate<? super T> predicate);
//是否所有的Cat的价格都大于2000
boolean allMatch = catList.stream().allMatch(cat -> cat.getPrice() > 2000);
System.out.println(allMatch); //false
System.out.println();
//anyMatch() :boolean anyMatch(Predicate<? super T> predicate);
//是否存在的Cat的价格大于2000
boolean anyMatch = catList.stream().anyMatch(cat -> cat.getPrice() > 2000);
System.out.println(anyMatch); //true
System.out.println();
//noneMatch() :boolean noneMatch(Predicate<? super T> predicate); 检查是否没有匹配的元素
//是否没有Cat的价格大于5000
boolean noneMatch = catList.stream().noneMatch(cat -> cat.getPrice() > 5000);
System.out.println(noneMatch); //true
System.out.println();
//findFirst() :Optional<T> findFirst();
//返回第一个元素
Optional<Cat> first = catList.stream().findFirst();
System.out.println(first);
System.out.println();
//findAny() :Optional<T> findAny();
//返回第一个元素
Optional<Cat> any = catList.stream().findAny();
System.out.println(first);
System.out.println();
//count() :long count();
//返回大于2000的个数
long count = catList.stream().filter(cat -> cat.getPrice() > 2000).count();
System.out.println(count);
System.out.println();
//max() :Optional<T> max(Comparator<? super T> comparator);
//返回最高价格
Stream<Double> priceStream = catList.stream().map(cat -> cat.getPrice());
Optional<Double> max = priceStream.max((cat1price, cat2price) -> Double.compare(cat1price,cat2price));
System.out.println(max);
System.out.println();
//min() :Optional<T> min(Comparator<? super T> comparator);
//返回最低价格的Cat
Optional<Cat> min = catList.stream().min((cat1, cat2) -> Double.compare(cat1.getPrice(), cat2.getPrice()));
System.out.println(min);
System.out.println();
//forEach() : 遍历
catList.stream().forEach(System.out::println);
}
//2. 规约
@Test
public void test2(){
//reduce() :T reduce(T identity, BinaryOperator<T> accumulator);
//计算1到10的和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer sum = list.stream().reduce(0, Integer::sum);
System.out.println(sum);
System.out.println();
//reduce() :Optional<T> reduce(BinaryOperator<T> accumulator);
//计算Cat的价格总和
List<Cat> catList = CatData.getCatList();
Stream<Double> priceStream = catList.stream().map(cat -> cat.getPrice());
Optional<Double> priceSum = priceStream.reduce(Double::sum);
System.out.println(priceSum);
System.out.println();
}
//3. 搜集
@Test
public void test3(){
//collect() :将流转换成其他形式
//查找价格大于2000的Cat 并放入Set/List
List<Cat> catList = CatData.getCatList();
Stream<Cat> catStream = catList.stream().filter(cat -> cat.getPrice() > 2000);
List<Cat> list = catStream.collect(Collectors.toList()); //toSet()/toCollection()
list.forEach(System.out::println);
System.out.println();
}
}