[Java8新特性]:Stream API
Stream API
(1)、Stream 是Java8中处理集合的关键抽象概念,它可以指定用户希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。
使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。简而言之,Stream API提供了一种高效且易于使用的处理数据的方式。
(2)、什么是 Stream
流 (Stream) 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。
“集合讲的是数据,流讲的是计算! ”
注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
(3)、Stream的操作三个步骤
创建Stream:一个数据源(如:集合、数组),获取一个流
中间操作:一个中间操作链,对数据源的数据进行处理
终止操作( ( 终端操作) ):一个终止操作,执行中间操作链,并产生结果
流进行了终止操作后,不能再次使用
(4)、创建 Stream
Collection提供了两个方法stream()与parallelStream()
@Test
public void Test06(){
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();//获取一个顺序流
Stream<String> stringStream = list.parallelStream();//获取一个并行流
}
通过Arrays中的stream()获取一个数组流
@Test
public void Test07() {
int[] m = {1, 2, 3, 4, 5, 6};
IntStream stream = Arrays.stream(m);
}
通过 Stream 类中静态方法 of()
@Test
public void Test08(){
Stream<Integer> integerStream = Stream.of(1, 2, 300);
}
创建无限流
@Test
public void Test09() {
//迭代
Stream<Integer> iterate = Stream.iterate(100, (x) -> x + 2).limit(5);
iterate.forEach(System.out::println);
//生成
Stream<Double> limit = Stream.generate(Math::random).limit(5);
limit.forEach(System.out::println);
}
(5)、Stream的中间操作
多个中间操作可以连接起来形成一个 流水线,除非流水线上触发终止操作,否则 中间操作不会执行任何的处理!而在终止操作时一次性全部 处理,称为“惰性求值”。
筛选与切片
@Test
public void Test10(){
//排除与截断
Stream<Integer> integerStream = Stream.iterate(100, (x) -> x + 2)
.filter((m) -> m < 200)
.limit(10);
//去重与跳过
Stream<Integer> distinct = Stream.of(1, 2, 5, 2, 3, 6, 7)
.distinct()
.skip(2);
integerStream.forEach(System.out::println);
System.out.println("=======");
distinct.forEach(System.out::println);
}
@Test
public class Demo2 {
List<Student> stu = Arrays.asList(
new Student("小明", 5),
new Student("花花", 10),
new Student("小芳", 18),
new Student("李明", 14),
new Student("珊珊", 21)
);
@Test
public void Test1(){
Stream<Student> stream = stu.stream()
.filter((x) -> x.getAge() < 15);
//内部迭代:迭代操作由Stream API完成
stream.forEach(System.out::println);
//外部迭代
Iterator<Student> iterator = stu.stream().iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
@Test
public void Test2(){
Stream<Student> studentStream = stu.stream()
.filter((e) -> {
System.out.println("执行!");
return e.getAge() > 12;
});
studentStream.forEach(System.out::println);
}
@Test
public void Test03(){
Stream<Student> studentStream = stu.stream()
.filter((e) -> {
System.out.println("执行");
return e.getAge() > 12;
})
.skip(2);
studentStream.forEach(System.out::println);
}
}
映射
@Test
public void Test1() {
List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
Stream<Stream<Character>> stream = strList.stream()
.map(Demo3::filterCharacter);
stream.forEach(System.out::println);
Stream<Character> stream1 = strList.stream().flatMap(Demo3::filterCharacter);
stream1.forEach(System.out::println);
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
排序
@Test
public void Test02() {
Stream<Integer> limit = Stream.generate(Math::random)
.map(x -> (int)(x * 10))
.limit(10)
.sorted((x,y) -> Integer.compare(x,y));
limit.forEach(System.out::println);
}
(6)、Stream的终止操作
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是void 。
查找与匹配
@Test
public void Test03(){
List<Student> stu = new Demo2().stu;
boolean b = stu.stream()
.allMatch((e) -> e.getAge() == 15);
System.out.println(b);
Optional<Student> first = stu.stream()
.findFirst();
System.out.println(first);
}
归约
Integer reduce = Arrays.asList(1, 2, 3, 7, 6, 5, 4, 3, 2, 3, 4, 5, 6, 7).stream().reduce(0, (x, y) -> x + y);
收集
Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
@Test
public void Test05() {
List<String> collect = Arrays.asList("学习", "我心中", "的热爱", "未来").stream().collect(Collectors.toList());
System.out.println(collect);
String collect1 = Arrays.asList("学习", "我心中", "的热爱", "未来").stream().collect(Collectors.joining());
System.out.println(collect1);
HashSet<String> collect2 = Arrays.asList("学习", "我心中", "的热爱", "未来").stream().collect(Collectors.toCollection(HashSet::new));
System.out.println(collect2);
}