今天小编学习了Stream流,Stream流是Java8新增的抽象流,在我看来,Stream流和输入输出IO流不同,并不是对文件的内容进行读写,它可以对内存中的数据进行一次性的处理,并以我们想要的形式进行输出,形容得有点抽象,让我们继续往下看!
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作 (terminal operation)得到前面处理的结果。
Stream(流)是一个来自数据源的元素队列并支持聚合操作。
- 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源流的来源。 可以是集合,数组等。
- 聚合操作类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted 等。
Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。
Stream的操作三个步骤
1.创建Stream
一个数据源(如:集合、数组),获取一个流。
2.中间操作
一个中间操作链,对数据源的数据进行处理。
3.终止操作
一个终止操作,执行中间操作链,并产生结果。
创建Stream
public class TestStreamAPI1 {
// 创建Stream
public void test1() {
// 1、可以通过Conllection系列集合提供的顺序流stream()或并行流
parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
stream1 = list.parallelStream();
// 2、通过Arrays中的静态方法stream()获取数据流
Integer ints[] = new Integer[10];
Stream<Integer> stream2 = Arrays.stream(ints);
// 3、通过Stream类中的静态方法of()
Stream<String> stream3 = Stream.of("aa", "bb", "cc");
String str[] = new String[10];
Stream<String> stream4 = Stream.of(str)
}
}
Stream的中间操作
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,称为”惰性求值”。
筛选和切片和跳过和去重
筛选filter
List<String> list=new ArrayList<String>();
list.add("sad");
list.add("asdasadsa");
list.add("ddasd");
list.add("adas");
list.add("fdsf");
list.add("asda");
// filter-接收Lambda,从流中排除某些元素
list=list.stream().filter((a)->{return a.length()>4;}).collect(Collectors.toList());
// 终止操作:一次性执行全部内容,即“惰性求值
list.forEach(System.out::println);
切片limit
// limit-截断流,使其元素不超过给定数量
Stream<String> stream=list.parallelStream();
stream.limit(3).forEach(System.out::println);
跳过skip
// skip-跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空
流。
stream=list.parallelStream();
stream.skip(1).forEach(System.out::println);
去重disinct
// distinct-筛选,通过流所生产元素的hashCode()和equals()去除重复元素
stream=list.parallelStream();
stream.distinct().forEach(System.out::println);
排序
sorted(Comparable)-自然排序
// sorted(Comparable)-自然排序
Stream<Integer> stream=list.stream();
stream.sorted().forEach(System.out::println);
System.out.println("------------------------------");
sorted(Comparator)-定制排序
// sorted(Comparator)-定制排序
// 需求:按年龄排序,年龄一样按姓名排序
List<Student> list=new ArrayList<Student>();
list.add(new Student("zhasan",18,"nan"));
list.add(new Student("zhasan1",19,"na"));
list.add(new Student("zhasan2",20,"nan1"));
list.add(new Student("zhasan3",14,"na2"));
list.add(new Student("zhasan4",15,"nan5"));
list.stream().sorted((e1, e2) -> {
if(((Integer)e1.getAge()).equals(e2.getAge()))
{return e1.getName().compareTo(e1.getName());}
else{
return ((Integer)e1.getAge()).compareTo(e2.getAge());
}
}).collect(Collectors.toList()).forEach(System.out::println);
终止操作
查找与匹配
// allMatch-检查是否匹配所有元素
boolean t=list.stream().allMatch((e)->"zhasan".equals(e.getName()));
System.out.println(t);
// anyMatch-检查是否至少匹配一个元素
boolean b2 = list.stream().anyMatch((e)->"zhasan".equals(e.getName()));
System.out.println(b2);
// noneMatch-检查是否没有匹配所有元素
boolean b3 = list.stream().noneMatch((e)->"zhasan".equals(e.getName()));
System.out.println(b3);
// findFirst-返回第一个元素
Optional<Integer> findFirst = list.stream().filter(t->t>50000).findFirst();
System.out.println(findFirst);
// anyMatch-检查是否至少匹配一个元素
Optional<Integer> findFirst2 = list.stream().filter(t->t>50000).findAny();
System.out.println(findFirst2);
// count-返回流中元素的总个数
Long count = list.stream().count();
System.out.println(count);
// max-返回流中最大值
Optional<Integer> op3 = list.stream().max((e1, e2) -> Double.compare(e1,
e2));
System.out.println(op3.get());
// min-返回流中最小值
Optional<Integer> op4 = list.stream().min(Double::compare);
System.out.println(op4.get());
stream=list.parallelStream();
注意:
1、Stream自己不会存储元素
2、Stream不会改变源对象。相反,会返回一个持有结果的新Stream。
3、Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。
总结:Stream流是一个非常便利的类,可以加强Collection容器的操作,让程序员拥有更多的操作空间!
居安思危,思则有备,有备无患!