Java 8 新特性(二)Stream 集合的流式编程

Stream–集合流

简介

Stream是对集合操作的增强,流不是集合的元素,不是一种数据结构,不负责数据的存储。流更像是一个迭代器,可以单向的遍历集合中的每一个元素,并且不可循环。

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

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

流式编程的步骤

  1. 获取数据源:将集合的数据读到一个流中;
  2. 中间操作:对流进行处理,得到的结果仍然是一个流对象;
  3. 终止操作:对流中的数据整合,关闭流对象。

:中间操作和终止操作时,基本上的方法都是函数式接口,需要lamda表达式来达到简化代码的目得。

1、数据源的获取

将数据读到一个流中,对流进行的操作不会影响数据源的数据,筛选的只是流中的所剩数据

//集合
public static Stream<Integer> getDatasource(){
    
    
    List<Integer> list = new ArrayList<>();      
    Collections.addAll(list,1,2,3,4,5,6,7,8,9);        
    return list.stream();//同步流       
    //return list.parallelStream();//异步流
}

//包装类数组
public static Stream<Integer> getAraayDatasource(){
    
    
    Integer[] array = new Integer[]{
    
    1,2,3,4,5,6,7,8,9};
    Stream<Integer> stream = Arrays.stream(array);
    return stream;
}

//基本数据数组
public static IntStream getIntDatasource(){
    
    
    int[] array = new int[]{
    
    1,2,3,4,5,6,7,8,9};
    IntStream intStream = Arrays.stream(array);
    return intStream;
}

2、终止操作

通过最终操作提取出流中想要的数据,之后会销毁这个流。操作关闭的流会抛异常。

  • collect:将流中的数据收集起来,对这些数据进行处理。
public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();

    //[1, 2, 3, 4, 5, 6, 7, 8, 9]
    //Set<Integer> set = stream.collect(Collectors.toSet());
    
    //{2=3, 3=4, 4=5, 5=6, 6=7, 7=8, 8=9, 9=10, 10=11}
    //Map<Integer, Integer> map = stream.collect(Collectors.toMap(i -> i + 1, i -> i + 2));
    
    //[1, 2, 3, 4, 5, 6, 7, 8, 9]
    List<Integer> list = stream.collect(Collectors.toList());

    System.out.println(list);
}
  • reduce:将流中的数据按一定的规则聚和起来。方法中一个返回值两个参数的函数式接口
public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();
    Optional<Integer> integerOptional = stream.reduce((p1, p2) -> p1 + p2);
    Integer integer = integerOptional.get();
    System.out.println(integer);//45

}
  • count:统计流中的数据数量
public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();
    System.out.println(stream.count());
}
  • foreach:遍历流中的数据。方法中一个参数没有返回值的函数式接口
public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();
    stream.forEach(System.out::println);
}
  • max&min:按照指定的规则找出最大最小值
public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();
    Integer max = stream.max(Integer::compareTo).get();
    Integer min = stream.min(Integer::compareTo).get();
}
  • Matching:

    allmatch:流中元素都匹配规则,返回true

    anymstch:流中任意元素满足规则,返回true

    nonematch:流中元素都不满足规则,返回true

public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();
    //System.out.println(stream.allMatch(integer -> integer > 5));//false
    //System.out.println(stream.anyMatch(integer -> integer > 5));//true
    System.out.println(stream.noneMatch(integer -> integer <0));//true
}
  • find

    findfirst:返回流中的第一个元素;

    firstany:返回流中的任意(一般为第一个);多线程时不一定

public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();//并行流
    //System.out.println(stream.findFirst().get());//1
    System.out.println(stream.findAny().get());//6
}
---
public static void main(String[] args) {
    
    
    Stream<Integer> stream = Datasource.getDatasource();//串行流
    //System.out.println(stream.findFirst().get());//1
    System.out.println(stream.findAny().get());//1
}
  • IntStream的另外的终止操作
public static void main(String[] args) {
    
    
    IntStream intStream = Datasource.getIntDatasource();
    
    int asInt = intStream.max().getAsInt();//最大值
    int asInt1 = intStream.min().getAsInt();//最小值
    int sum = intStream.sum();//和
    long count = intStream.count();//元素个数
    double v = intStream.average().getAsDouble();//平均值
    
    IntSummaryStatistics summaryStatistics = intStream.summaryStatistics();//数据分析合集
    
    double average = summaryStatistics.getAverage();
    long count1 = summaryStatistics.getCount();
    int max = summaryStatistics.getMax();
    int min = summaryStatistics.getMin();
}

3、中间操作

对流处理可进行多次

  • filter:条件过滤,剔除不满足条件的元素
stream.filter(integer -> integer>5).forEach(System.out::println);
  • distinct:去除流中重复的元素。去重原则与HashSet一样,实体类需要重写hashcode()和equls
stream.distinct().forEach(System.out::println);
  • sorted:

    1. [无参]排序实体类需实现Comparable接口;

    2. [有参]自定义接口实现

stream.sorted().forEach(System.out::println);
  • limit & skip:

    limit:限制,截取一定数量的数据

    skip:跳过,掉过指定数量的数据

stream.distinct()
    .limit(5)
    .skip(2)
    .sorted()
    .forEach(System.out::println);
  • map & flatmap

    map:提供规则,用新的数据替换流中的数据

    flatmap:扁平化映射,将流中的容器中的数据直接读取到流中

 stream.map(integer -> "第"+integer+"个数据").forEach(System.out::println);
//第1个数据、第2个数据、第3个数据、第4个数据、第5个数据、第6个数据、第7个数据、第8个数据、第9个数据
public static void main(String[] args) {
    
    
    String[] array = new String[]{
    
    "hello","world"};
    Stream<String> stream = Arrays.stream(array);
    //统计出现的字符
    // stream.map(String::toCharArray)
    	.forEach(e-> System.out.println(e));//{'h','e','l','l','o'} ,{'w','o','r','l','d'}
    stream.map(s->s.split(""))//{"h","e","l","l","o"} ,{"w","o","r","l","d"}
        .flatMap(Arrays::stream)//{"h","e","l","l","o","w","o","r","l","d"}
        .distinct()//{"h","e","l","o","w","r","d"}
        .forEach(System.out::print);//helowrd
}
  • mapToInt:一个参数,int类型的返回值,返回流对象为IntStream
IntStream intStream = stream.mapToInt(Integer::byteValue);
IntSummaryStatistics summaryStatistics = intStream.summaryStatistics();

4、Collectors工具类的其他操作

  1. maxby()、minby() 、summingInt()、averagingInt()、summarizingInt():都可通过mapToInt()替换
  2. joining:将流中的数据拼接成一个字符串,只能操作Stream
public static void main(String[] args) {
    
    
    String[] array = new String[]{
    
    "hello","world","java","c++"};

    Stream<String> stream = Arrays.stream(array);
    //参数一:分隔符
    //参数二:前缀
    //参数三:后缀
    String collect = stream.collect(Collectors.joining("-", "[", "]"));

    System.out.println(collect);//[hello-world-java-c++]
}

猜你喜欢

转载自blog.csdn.net/qq_38473355/article/details/108720955