JDK1.8新特性

1.集合流的简介

1.1、 集合流式编程的简介

Stream是JDK1.8之后出现的新特性,也是JDK1.8新特性中最值得学习的两种特性之一。(另外一个是lambda表达式)。
Stream是对集合操作的增强,流不是集合的元素,不负责数据的储存。流更像是一个迭代器,可以单项的遍历一个集合中的每一个元素,并且不可循环。

1.2、为什么要使用集合的流式编程

有些时候,对集合中的元素进行操作的时候,需要使用到其他操作的结果。在这个过程中,集合的流式编程可以大幅度的简化代码的数量,将数据源中的数据读取到一个流中,可以对这个流中的数据进行操作(删除、过滤、映射…)。每次的操作结果也是一个流对象,可以对这个流进行其他操作。

1.3、使用流式编程的步骤

通常情况下,对集合中的数据使用流式编程需要经过以下三步:
1、获取数据源,将数据中的数据读取到流中。
2、对流中的数据进行各种各样的处理。
3、对流中的数据进行处理。

在上述的三个过程中,过程2中,有若干方法,可以对流中的数据进行各种各样的操 作,并且返回流对象本身,这样的操作被称为–中间操作;过程3中,有若干方法,可以对流中的数据进行各种处理,并关闭流,这样的操作被称为–最终操作。

在中间操作和终止操作中,基本上所有的方法参数都是函数式接口,可以使用lambda表达式来实现。使用集合的流式编程,来简化代码量,是需要对lambda表达式做到熟练掌握。

2、数据源的获取

2.1、数据源的简介

数据源,顾名思义,既是流中的数据来源,也是集合集合的流式编程的第一步,将数据源中的数据读取到流中进行处理。注意:将数据读取到到流中进行处理的时候,与数据源中的数据没有关系,也就是说,中间操作对流中的数据进行处理、过滤、放映、排序…,此时是不会影响数据源中的数据的。’

2.2、 数据源的获取

这个过程中,其实是将一个容器中数据读取到一个流中,因此无论什么容器作为数据源,读取到流中的方法返回值一定是一个Stream。

//1、通过Collection接口中的Stream()方法获取
Stream<Integer> stream = list.stream();
//2.通过Collection接口中的parallelStream()方法获取
Stream<Interger> stream = list.parallelStream();

关于stream() 和 parallelStream()
他们都是Collcction集合获取数据源的方法,不同点在于strcam()方法获取的数据是串行的。parallelStream()获取的数据源是并行的。parallelStream()内部集成了多个线程对流的中的数据进行操作,效率更高。

3、最终操作

3.1、最终操作简介

  将流中的的操作整合到一起,可以存入一个集合,也可以直接对流中的数据进行遍历、数据统计…通过最终操作,需要掌握如何从流中提取出来我们想要的信息

注意事项:最终操作之所以叫最终操作是因为在最终操作执行后,会关闭这个流,流中的所有数据都会销毁,如果使用了一个已经关闭的流,会出现异常。

3.2、collect

  将流中的数据收集到一起,对这个数据进行一些处理。最常见的处理,就是将流中的数据存入一个集合。
collect方法参数,是一个Collector接口,而且这个接口并不是一个函数式接口,实现这个接口可以自定义收集规则,但是,绝大多数情况下不要自定义。直接使用Collectors工具类提供的方法即可。

//1.1 转成List
List<Intcger> result1 = list.stroom().collect(Collectors.toList());
Sysrem.out.println(result1);

//1.2 转成Set
set<Intcger> result2 = list.stroom().collect(Collectors.toList());
Sysrem.out.println(result2);

//1.3、转成Map,提供两个函数接口实现,分别生成键的生成规则和值的生成规则
Map<Intcger,Intcger> result3 = list.stream().collect(collect.toMap(ele ->ele/ 10,clc->clc ));
Sysrem.out.println(result3);

3.3、reduce

  将流中的数据按照一定的规则聚合起来。

//将流的元素,逐一带入到这个运算方法中进行运算
//最终的运算结果,得到的其实是一个Optional类型,需要使用get()获取到里面的数据
int result4 = list.stream().reduce((e1,e2)->e1+e2).get();
System.out.println(result4);

3.4、count

统计流中的元素数量:

long result5 = list.stream().count();
System.out.println(result5);

3.5、forEach

  迭代、遍历流中的数据:

list.stream().forEach(System.out::println);

3.6、max & min

  获取流中的最大元素、最小元素:

//最大值
Integer result6 = list.stream().max(Integer::compareTn).get();
System.out.println("max is : " + result6);
//最小值
Integer result7 = list.stream().min(Integer::compareTn).get();
System.out.println("min is : " + result7);

3.7、Matching

  allMatching:只有当流中所有的元素都匹配指定的规则,才会返回true

  anyMatching:只要流中有任意的数据满足指定规则,都会返回true

  noneMatching:只有当流中的所有元素都不能满足指定的规则,才会返回true

//判断流中是否所有的元素都大于50
boolean result8 = list.stream().allMatch(ele -> ele > 50);
System.out.println(result8);
//判断流中是否有大于50的元素
boolean result9 = list.stream().anyMatch(ele -> ele > 50);
System.out.println(result9);
//判断流中是否没有奇数
boolean result10 = list.stream().noneMatch(ele -> ele % 2 != 0);
System.out.println(result10);

3.8、find

  findFirst:从流中获取一个元素(一般情况下,是获取的开头元素)
  findAny:从流中获取一个元素(一般情况下,是获取的开头元素)
  这两个方法,绝大部分情况下是完全相同的,但是在多线程的环境下,findAny和find返回的结果可能不一样。

Integer result11 = list.rarallelStream().findFirst().get();
System.out.println(result11);

Integer result12 = list.rarallelStream().findAny().get();
System.out.println(result12);

3.9、 最终操作的注意事项

  最终操作,会关闭流。 如果-个流被关闭了,再去使用这个流,就出出现异常。

// 最终操作错误示范
Stream<Integer> stream = list.stream();

long count = strean.count();

stream.forEach(Systerm.out:: print1n);

Exception in thread "main" java. lang. IllegalStateException: stream has already beenoperated upon or closed java.util.stream.AbstractPipeline . sourceStageSpliterator(AbstractPipeline . java:279)at java.util. stream. ReferencePipel ineSHead . forEach( ReferencePipeline . java:580)at com.qf .cstream .FinaloperationDemo.main(FinaloperationDeno.java:78)

4、中间操作

4.1、中间操作简介

将数据错数据源中读取到流中,中间操作就是对流中的数据进行各种各样的操作,处理。中间操作可以连续操作,每一个操作返回值是一个Stream对象,可以继续进行其他操作,直到最终操作。

4.2、filter

条件过滤,仅保留流中满足指定条件的数据,其他不满足的数据,其他不满足的数据都会被删除。

list.stream().filter(ele -> ele.lemgth() > 5).forEach(System.out::println);

4.3、distinct

去重集合中重复的元素,这个方法没有参数。去重规则与HashSet相同。

list.stream().distinct().forEach(System.out::println);

4.4、sorted

将流中的数据进行排序

//按照流中的元素对应类,实现的Comparable接口中的方法实现排序
list.stream().sorted().forEach(System.out::println);
//将流中的数据按照指定的规则排序
list.stream().sorted((e1,e2) -> e1.length() - e2.length()).forEach(System.out::println);

4.5、limit & skip

limit:限制、截取流中指定数量的元素

skip:跳过,跳过流中发指定数量的元素

//跳过开头的指定的元素
list.stream().skip(3).forEach(System.out::println);
//截取指定数量的元素
list.stream().linit(3).forEach(System.out::println);
//配合使用,截取部分元素
list.stream().skip(5).linit(2).forEach(System.out::println);

4.6、map & flatMap

map:对流中的数据进行映射,用新的数据替换旧的数据。

list.stream().map(ele -> ele + "txt").forEach(System.out::println);

map最主要就是来做元素的替换,其实map是一个元素的映射。
flatMap也是元素的映射,flatMap是扁平化映射。

4.7mapToint

将流中的数据替换位int类型,此时得到intStream结果。

double avg = list.stream().mapToInt(Person::getAge).average().getAsDouble();
system.out.println(avg);

5.Collectors工具类

Collectors是一个工具类,里面封装了很多方法,可以很方便的获取到一个Collector接口的实现类对象,从而可以使用collect()方法,对流中的数据进行各样的整合、处理。

Collectors.toList() : 将流中的数据聚合到一个List集合中
Collectors.toSet() : 将流中的数据聚合到一个Set集合中
Collectors.toMop() : 将流中的数据聚合到一个Mop集合中

maxBy() : 按照指定规则找到流中最大的元素,等同于max
minBy() : 按照指定规则找到流中最小的元素,等同于min

joining() : 将流中的数据拼接成一个字符串。注意:只能操作流中是String的数据
summingInt() : 将流中的数据映射为int类型的数据并求和
averagingInt() :将流中的数据映射为int类型的数据并求平均值
summarizingInt() :将流中的数据映射为int类型的数据并获取描述信息

//maBxy: 按照指定规则找到流中最大的元素,等同于max
Student max = list.stroam().collect(Collect,maxBy((s1,s2) -> s1.getScore() - s2.getScore())).get();
System.out.println(max);
//minBy: 按照指定规则找到流中最小的元素,等同于min
Student max = list.stroam().collect(Collect,minBy((s1,s2) -> s1.getScore() - s2.getScore())).get();
System.out.println(min);
//将流中的数据拼接起来
String s1 = lidt.stream().map(Student::getName).collect(Collectors.joining());
System.out.println(s1);
//将流中的数据拼接起来,并按照指定的分隔符进行分割
String s2 = lidt.stream().map(Student::getName).collect(Collectors.joining(", "));
System.out.println(s2);
//将流中的数据拼接起来,以指定的分隔符进行分割,并添加前缀和尾缀
String s3 = lidt.stream().map(Student::getName).collect(Collectors.joining(", ","{","}"));
System.out.println(s3);
//将流中的数据映射为int类型的数据并求和
int sum = lidt.stream().collect(Collectors.summingInt(Student::getScore));
System.out.println(sum);
//将流中的数据映射为int类型的数据并求平均值
int average = lidt.stream().collect(Collectors.averagingInt(Student::getScore));
System.out.println(average);
//将流中的数据映射为int类型的数据并获取描述信息
IntSummaryStatistics summaryStatistics = list.stream().collect(Collectors.summarizingInt(Student::getScore));
System.out.println(summaryStatistics);
System.out.println(summaryStatistics.getCount());
System.out.println(summaryStatistics.getSum());
System.out.println(summaryStatistics.getMax());
System.out.println(summaryStatistics.getMin());
System.out.println(summaryStatistics.getAverage());

6、综合案例

需求:一个集合中储存了若干个Student对象,要求查询出一下结果:
1、所有及格的学生成绩
2、所有及格的学生姓名
3、所有学生的平均成绩
4、班级的前三名(按照成绩)
5、班级3-10名(按照成绩)
6、所有不及格的学生成绩
7、将及格的学生按照成绩降序输出所有信息
8、班级学生的总分

 public class Studdent{
   private String name;
   private int score;

   public String getName() {
       return name;
   }

   public int getscore(){
       return score;
   }

   public Student(String name, int score){
       this.name = name;
       this.score = score;
   }

   public String toString(){
       return String.lormat("姓名:%s,成绩:%d", name,score);
   }
}
import java.util.list;
import java.util.ArrayList;


 public class Program {
   public static void main(String[] args){
       //0、实例化集合,储存学生对象
       List<Student> list = new ArrayList<>();
       Collections.addAll(list
           new Student("小明", 89),
           new Student("小王", 81),
           new Student("小红", 99),
           new Student("张三", 100),
           new Student("李四", 51),
           new Student("王五", 39),   
       );
       
       //1、所有及格学生信息
       list.stream()
           .filter(s -> s.getScore() >= 60)
           .forEach(System.out::println);


       //2、所有及格学生的姓名
       list.stream()
           .filter(s -> s.getScore() >= 60)
           .map(Student::getName)
           .forEach(System.out::println);

       //3、所有学生的平均成绩
       double average = list.stream()
                            .mapToInt(Student::getScore)
                            .average()
                            .getAsDouble();
       System.out.println(average);
       
       //4、班级前三名(按照成绩)
       List<Student> result1 = list.stream()
                                   .sorted((s1,s2) -> s2.getScore() - s1.getScore()
                                   .limit(3)
                                   .collect(Collectors.toList));
        result1.forEach(System.out::println);

       //5、班级的3-10名(按照成绩)
       List<Student> result2 = list.stream()
                                   .sorted((s1,s2) -> s2.getScore() - s1.getScore()
                                   .limit(10)
                                   .skip(2)
                                   .collect(Collectors.toList));
         result2.forEach(System.out::println);

       //6.所有不及格的学生平均成绩
       doble average1 = list.stream()
                            .filter(s -> s.getScore() < 60)
                            .mapToInt(Student::getScore)
                            .average()
                            .getAsDouble();
      System.out.println(average1);

      //7、将及格的学生按照成绩降序输出所有信息
      list.stream()
          .filter(s -> s.getScore() >= 60)
          .sorted((s1,s2) -> s2.getScore() - s1.getScore()
          .forEach(System.out::println);

       //8、班级学生的总分
       long sum = list.stream()
                      .mapToInt(Student::getScore)
                      .sum();
       System.out.println(sum);

   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值