java型特性——Stream API(Stream流)
程序员文章站
2022-05-28 11:36:43
...
Java8新特性之Stream API
Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。Stream 是
Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作,在新版的JPA中,也已经加入了Stream。如:
@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();
Stream<User> readAllByFirstnameNotNull();
@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);
Stream的操作步骤
Stream有如下三个操作步骤:
一,创建Stream
从一个数据源,如集合、数组中获取流。
二,中间操作
一个操作的中间链,对数据源的数据进行操作。
三,终止操作
一个终止操作,执行中间操作链,并产生结果。
要注意的是,对流的操作完成后需要进行关闭操作(或者用JAVA7的try-with-resources)。
四,Stream和parallelStream的区别
创建Stream
/**
* 1.通过Collection对象的Stream()和ParalleStream() 并行的,效率高
*/
@Test
public void test01(){
List<String> wordsList = GetListData.wordsList;
Stream<String> stream = wordsList.stream();
stream.forEach(System.out::println);
//通过方法引用对其进行简化
GetListData.wordsList.stream().forEach(System.out::println);
}
/**
* 2.通过Arrays工具类的stream方法
*/
@Test
public void test02(){
String [] strArray = new String[] {"a", "b", "c"};
Arrays.stream(strArray).forEach(System.out::println);
}
Stream API本身自带的方法:
/**
* 3.通过Stream的一些方法of、iterate、generate
*/
@Test
public void test03(){
Stream<Integer> stream = Stream.of(10, 20, 30, 40, 50);
stream.forEach(System.out::println);
Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);
iterate.limit(10).forEach(System.out::println);
Stream<Integer> generate = Stream.generate(() -> new Random().nextInt(100));
generate.limit(5).forEach(System.out::println);
}
不同的数据类型,可以创建不同类型的Stream:
/**
* 通过IntStream、DoubleStream、LongStream....
*/
@Test
public void test04(){
IntStream.of(10, 20, 30, 40).forEach(System.out::println);
}
中间操作:Stream的聚合操作
常用的中间操作有五种:filter, limit ,skip, distinct, sort ,map
filter :接收Lambda,从流中排除某些操作;
//判断年龄大于20岁的同学
//通常会在springcloud中的zuul网关会出现
List<Student> collect = students.stream().filter(student -> student.getAge() >= 20).collect(Collectors.toList());
collect.forEach(System.out::println);
limit :截断流,使其元素不超过给定对象
//limit 等同于SQL语句中的limit
students.stream().limit(2).forEach(System.out::println);
skip:跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
//skip 跳过前两条
students.stream().skip(2).forEach(System.out::println);
distinct :筛选,通过流所生成元素的hashCode()和equals()去除重复元素。
//distinct 去重 依据equals hascode
students.stream().distinct().forEach(System.out::println);
sort :对数据进行排序
//sort 排序
//按照学生的年龄进行排序
students.stream().sorted((s1,s2)->Integer.compare(s1.getAge(),s2.getAge()))
.forEach(System.out::println);
map:能够获取流中的一部分
//map 能够获取流中的一部分 比如只拿到学生中的姓名
List<Integer> collect = students.stream().map(student -> student.getAge()).collect(Collectors.toList());
collect.forEach(System.out::println);
聚合中间函数
聚合中间函数 max min count reduce collect
//SpringData-jpa 通过id查询会返回Optional的对象
//为了防止空指针
//获取最大
Optional<Student> max = students.stream().max((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
System.out.println(max.get().getAge());
//获取最小
Optional<Student> min = students.stream().min((s1, s2) -> Integer.compare(s1.getAge(), s2.getAge()));
System.out.println(min.get().getAge());
//总和
System.out.println(students.stream().count());
//reduce 统计年龄的总和
Optional<Integer> reduce = students.stream().map(student -> student.getAge()).reduce((x, y) -> x + y);
System.out.println(reduce.get());
//collect 返回一个新的流
List<Integer> collect = students.stream().map(student -> student.getAge()).collect(Collectors.toList());
collect.stream().forEach(System.out::println);
Stream和parallelStream的区别
parallelStream是多线程操作
Stream是单线程操作
//创建较大数据,容易看出两者区别
List<String> list = new ArrayList<>();
for (int i=0;i<10000000;i++){
list.add(UUID.randomUUID().toString());
}
//获取操作开始时的时间戳
long start = System.currentTimeMillis();
//单线程操作
list.stream().sorted().count();
//多线程操作
list.parallelStream().sorted().count();
//获取操作结束时的时间戳
long end = System.currentTimeMillis();
//获取这一段代码执行的时间是多长
System.out.println(end-start);
//最后结果为
stream的操作时间为:6864
parallelStream的操作时间为:2565
每天一个装逼小技巧,毕竟我们是专业的
上一篇: GUI interface的设计
下一篇: Java GUI事件监听