JDK1.8新特性Stream流式操作的具体使用

一. 前言

随着Java的发展,越来越多的企业开始使用JDK1.8 版本。JDK1.8 是自 JDK1.5之后最重要的版本,这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。本次文章将着重学习Stream。

Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

+--------------------+    +------+  +------+  +---+  +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+    +------+  +------+  +---+  +-------+

简而言之,Stream API提供了一种高效且易于使用的处理数据的方式。

二. 什么是Stream

1.Stream(流)是一个来自数据源的元素队列并支持聚合操作。

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

2.和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

特点:
1.Stream 不是数据结构,不会保存数据。
2.Stream 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)
3.惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。

三. 关于Stream API

1. Stream API分类

Stream 操作分为中间操作或者终止操作两种,终止操作返回一特定类型的计算结果,而中间操作返回Stream本身,Stream 的操作类型具体分类如下:

解释:

  • 无状态:指元素的处理不受之前元素的影响;
  • 有状态:指该操作只有拿到所有元素之后才能继续下去。
  • 非短路操作:指必须处理所有元素才能得到最终结果;
  • 短路操作:指遇到某些符合条件的元素就可以得到最终结果,如 A || B,只要A为true,则无需判断B的结果。

2. 如何使用Stream流?

使用Stream流分为三步。

创建Stream

一个数据源(如:集合、数组),获取一个Stream流。

中间操作

一个中间操作链,对数据源(如:集合、数组)的数据进行处理。

终止操作

一个终止操作,执行中间操作链,并产生一个计算结果。

3. Stream的中间操作和结束操作

中间操作

filter: 过滤流,过滤流中的元素,返回一个符合条件的Stream

map: 转换流,将一种类型的流转换为另外一种流。(mapToInt、mapToLong、mapToDouble 返回int、long、double基本类型对应的Stream)

flatMap:简单的说,就是一个或多个流合并成一个新流。(flatMapToInt、flatMapToLong、flatMapToDouble 返回对应的IntStream、LongStream、DoubleStream流。)

distinct: 返回去重的Stream。

sorted: 返回一个排序的Stream。

peek: 主要用来查看流中元素的数据状态。

limit: 返回前n个元素数据组成的Stream。属于短路操作

skip: 返回第n个元素后面数据组成的Stream。

结束操作

forEach: 循环操作Stream中数据。

toArray: 返回流中元素对应的数组对象。

reduce: 聚合操作,用来做统计。

collect: 聚合操作,封装目标数据。

min、max、count: 聚合操作,最小值,最大值,总数量。

anyMatch: 短路操作,有一个符合条件返回true。

allMatch: 所有数据都符合条件返回true。

noneMatch: 所有数据都不符合条件返回true。

findFirst: 短路操作,获取第一个元素。

findAny: 短路操作,获取任一元素。

forEachOrdered: 暗元素顺序执行循环操作。

四. 如何获取Stream流

在 Java 8 中, 集合接口有两个方法来生成流:

  • stream() − 为集合创建串行流。
  • parallelStream() − 为集合创建并行流。

1. 常见几种集合流的创建

/**
 * stream,获取各种集合的stream流
 */
@Test
public void testCollectionStream(){
  //List集合
  List<String> stringList = new ArrayList<>();
  //Set集合
  Set<String> stringSet = new HashSet<>();
  //Map集合
  Map<String,Object> stringObjectMap = new HashMap<>();
  //数组
  String[] stringArray = {"张三三","李四","王五","王五","赵八",};

  //通过list获取stream流
  Stream<String> streamList = stringList.stream();
  //通过set获取stream流
  Stream<String> streamSet = stringSet.stream();
  //通过map获取stream流
  Stream<String> streamMap = stringObjectMap.keySet().stream();
  //通过array获取stream流
  Stream<String> streamArray1 = Stream.of(stringArray);
}

2. 构造流的几种常见方法

@Test
public void testCollectionStream(){
  // 1. Individual values
 Stream stream = Stream.of("a", "b", "c");

 // 2. Arrays
 String[] strArray = new String[]{"a", "b", "c"};
 stream = Stream.of(strArray);
 stream = Arrays.stream(strArray);

 // 3. Collections
 List<String> list = Arrays.asList(strArray);
 stream = list.stream();

}

五. Stream在代码中的使用方式

关于Stream的常见操作方式,主要分为两大类: 中间操作和终止操作 ,接下来就通过这两大分类,讲解下具体的语法用法。

1. 流的中间操作

1.1 筛选过滤

filter:过滤流中的某些元素

  /**
   * filter 方法 , 返回符合过滤条件的值
   */
  @Test
  public void testFilter() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.stream().filter(e -> e.contains("张")).forEach(System.out::println);
  }

filter多个过滤筛选条件

 /**
 * list集合stream流式操作
 */
 @Test
 public void testStreamList() {
   List<String> list = new ArrayList<>();
   list.add("张三三");
   list.add("李四");
   list.add("王五");
   list.add("孙七");
   list.add("赵八");
   list.stream().filter(e -> e.startsWith("张")) //过滤所有姓张的人
       .filter(e -> e.length() == 3) //过滤所有姓名是3个字的人
       .forEach(System.out::println); //遍历打印,System.out::println表明System.out调用println打印方法
 }

limit(n):获取前n个元素

 /**
   * limit 方法 ,返回前n个元素数据值组成的Stream。
   */
  @Test
  public void testLimit() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    list.stream().limit(3).forEach(System.out::println); //取前3个
  }

skip(n):跳过n元素,配合limit(n)可实现分页

 /**
   * skip方法 ,跳过前n个元素的中间流操作,返回剩下的值。
   */
  @Test
  public void testSkip() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    //list.stream().skip(3).forEach(System.out::println); //跳过前3个
    list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit实现分页
  }

distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素

 /**
   * distinct, 返回去重的Stream
   */
  @Test
  public void testDistinct() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    list.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
  }

1.2 排序

sorted():自然排序,流中元素需实现Comparable接口

 /**
   * sorted: 返回一个排序的Stream
   */
  @Test
  public void testSorted() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    list.stream().distinct().sorted().collect(Collectors.toList()).forEach(System.out::println);
  }

sorted(Comparator com):定制排序,自定义Comparator排序器

1.3 映射

map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

/**
  * 遍历map集合,截取substring(2)开始的值
  */
  @Test
  public void testMap() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    Stream<String> stream = list.stream().map(e -> e.substring(2));
    stream.forEach(System.out::println);
  }

forEach:ForEach流式遍历集合

 /**
   * forEach, ForEach流式遍历list集合
   */
  @Test
  public void testForEach() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.stream().forEach(System.out::println);
  }

2. 流的终止操作

2.1 匹配、聚合操作

allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false

 /**
   * allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
   */
  @Test
  public void testAllMatch() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    boolean b = list.stream()
        .allMatch(e -> list.size() > 8);
    System.out.println("b = " + b);
  }

noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false

  /**
   * noneMatch: 接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
   */
  @Test
  public void testNoneMatch() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    boolean b = list.stream().noneMatch(e->e.equals("张三"));
    System.out.println("b = " + b);
  }

anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false

/**
   * anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
   */
  @Test
  public void testAnyMatch() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    boolean b = list.stream().anyMatch(e -> e.equals("王二麻子"));
    System.out.println("b = " + b);
  }

findFirst:返回流中第一个元素

 /**
   * findFirst:返回流中第一个元素
   */
  @Test
  public void testFindFirsth() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    Optional<String> first = list.stream().findFirst();
    System.out.println("first = " + first.get());
  }

findAny:返回流中的任意元素

  /**
   * findAny:返回流中第一个元素
   */
  @Test
  public void testFindAny() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    Optional<String> any = list.stream().findAny();
    System.out.println("any = " + any.get());
  }

count:返回流中元素的总个数

/**
   * count,获取List集合的长度
   */
  @Test
  public void testCount() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    long count = list.stream().count();
    System.out.println("count = " + count);
    int size = list.size();
    System.out.println("size = " + size);
  }

2.2 Collector 工具库:Collectors

Collectors

Student s1 = new Student("aa", 10,1);
Student s2 = new Student("bb", 20,2);
Student s3 = new Student("cc", 10,3);
List<Student> list = Arrays.asList(s1, s2, s3);

//装成list
List<Integer> ageList = list.stream().map(Student::getAge).collect(Collectors.toList()); // [10, 20, 10]

//转成set
Set<Integer> ageSet = list.stream().map(Student::getAge).collect(Collectors.toSet()); // [20, 10]

//转成map,注:key不能相同,否则报错
Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge)); // {cc=10, bb=20, aa=10}

//字符串分隔符连接
String joinName = list.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)

//聚合操作
//1.学生总数
Long count = list.stream().collect(Collectors.counting()); // 3
//2.最大年龄 (最小的minBy同理)
Integer maxAge = list.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 20
//3.所有人的年龄
Integer sumAge = list.stream().collect(Collectors.summingInt(Student::getAge)); // 40
//4.平均年龄
Double averageAge = list.stream().collect(Collectors.averagingDouble(Student::getAge)); // 13.333333333333334
// 带上以上所有方法
DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Student::getAge));
System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());

//分组
Map<Integer, List<Student>> ageMap = list.stream().collect(Collectors.groupingBy(Student::getAge));
//多重分组,先根据类型分再根据年龄分
Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getType, Collectors.groupingBy(Student::getAge)));

//分区
//分成两部分,一部分大于10岁,一部分小于等于10岁
Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));

//规约
Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); //40  

六、Stream操作代码

为了方便小伙伴们看到这篇博客时,学习的更加轻松,这里贴出源码,小伙伴们学习是可贴到IDEA运行查看Stream过滤筛选的结果,以此对Stream的流式操作更加熟悉。

package com.java8.example.chapter3;

import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @desc: Stream流式操作
 * @author: cao_wencao
 * @date: 2020-09-17 15:24
 */
public class TestStreamList {

  /**
   * list集合stream流式操作
   */
  @Test
  public void testStreamList() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.stream().filter(e -> e.startsWith("张")) //过滤所有姓张的人
        .filter(e -> e.length() == 3) //过滤所有姓名是3个字的人
        .forEach(System.out::println); //遍历打印,System.out::println表明System.out调用println打印方法
  }

  /**
   * stream,获取各种集合的stream流
   */
  @Test
  public void testCollectionStream() {
    List<String> stringList = new ArrayList<>();
    Set<String> stringSet = new HashSet<>();
    Map<String, Object> stringObjectMap = new HashMap<>();
    String[] stringArray = {"张三三", "李四", "王五", "王五", "赵八",};

    //通过list获取stream流
    Stream<String> streamList = stringList.stream();
    //通过set获取stream流
    Stream<String> streamSet = stringSet.stream();
    //通过map获取stream流
    Stream<String> streamMap = stringObjectMap.keySet().stream();
    //通过array获取stream流
    Stream<String> streamArray1 = Stream.of(stringArray);

  }

  /**
   * forEach, ForEach流式遍历list集合
   */
  @Test
  public void testForEach() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.stream().forEach(System.out::println);
  }

  /**
   * filter 方法 , 返回符合过滤条件的值
   */
  @Test
  public void testFilter() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.stream().filter(e -> e.contains("张")).forEach(System.out::println);
  }

  /**
   * 遍历map集合,截取substring(2)开始的值
   */
  @Test
  public void testMap() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    Stream<String> stream = list.stream().map(e -> e.substring(2));
    stream.forEach(System.out::println);
  }

  /**
   * count,获取List集合的长度
   */
  @Test
  public void testCount() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    long count = list.stream().count();
    System.out.println("count = " + count);
    int size = list.size();
    System.out.println("size = " + size);
  }

  /**
   * limit 方法 ,返回前n个元素数据值组成的Stream。
   */
  @Test
  public void testLimit() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    list.stream().limit(3).forEach(System.out::println); //取前3个
  }

  /**
   * skip方法 ,跳过前n个元素的中间流操作,返回剩下的值。
   */
  @Test
  public void testSkip() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    //list.stream().skip(3).forEach(System.out::println); //跳过前3个
    list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit实现分页
  }

  /**
   * collect,将流转化为集合
   */
  @Test
  public void testCollect() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    List<String> collect = list.stream().skip(3).limit(2).collect(Collectors.toList());
    collect.forEach(System.out::println);
  }

  /**
   * distinct, 返回去重的Stream
   */
  @Test
  public void testDistinct() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    list.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
  }

  /**
   * sorted: 返回一个排序的Stream
   */
  @Test
  public void testSorted() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    list.stream().distinct().sorted().collect(Collectors.toList()).forEach(System.out::println);
  }

  /**
   * anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
   */
  @Test
  public void testAnyMatch() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    boolean b = list.stream().anyMatch(e -> e.equals("王二麻子"));
    System.out.println("b = " + b);
  }

  /**
   * noneMatch: 接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
   */
  @Test
  public void testNoneMatch() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    boolean b = list.stream().noneMatch(e->e.equals("张三"));
    System.out.println("b = " + b);
  }

  /**
   * allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
   */
  @Test
  public void testAllMatch() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    boolean b = list.stream()
        .allMatch(e -> list.size() > 8);
    System.out.println("b = " + b);
  }

  /**
   * findFirst:返回流中第一个元素
   */
  @Test
  public void testFindFirsth() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    Optional<String> first = list.stream().findFirst();
    System.out.println("first = " + first.get());
  }

  /**
   * findAny:返回流中第一个元素
   */
  @Test
  public void testFindAny() {
    List<String> list = new ArrayList<>();
    list.add("张三三");
    list.add("李四");
    list.add("李四");
    list.add("王五");
    list.add("王五");
    list.add("孙七");
    list.add("赵八");
    list.add("王二麻子");
    Optional<String> any = list.stream().findAny();
    System.out.println("any = " + any.get());
  }

  /**
   * max:返回流中元素最大值
   */
  @Test
  public void testMax() {
    List<Integer> list = new ArrayList<>();
    list.add(11);
    list.add(22);
    list.add(33);
    list.add(44);
    list.add(55);
    list.add(66);
    list.add(77);
    list.add(88);
    Integer integer = list.stream().max(Integer::compareTo).get();
    System.out.println("integer = " + integer);
  }

  /**
   * min:返回流中元素最小值
   */
  @Test
  public void testMin() {
    List<Integer> list = new ArrayList<>();
    list.add(11);
    list.add(22);
    list.add(33);
    list.add(44);
    list.add(55);
    list.add(66);
    list.add(77);
    list.add(88);
    Integer integer = list.stream().min(Integer::compareTo).get();
    System.out.println("integer = " + integer);
    list.stream().limit(1).limit(2).distinct().skip(3).filter(f -> f.equals(55)).forEach(System.out::println);
  }
}

总结

以上就是对于JDK1.8中Stream流式计算的一个简单介绍,关于JDK1.8中的新特性,用法远远不止这些,这篇文章只作为一个简单的入门使用,更多相关Java8 Stream流式操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java8中的Stream流式操作教程之王者归来

    前言 相对于Java8之前的Java的相关操作简直是天差地别,Java8 的流式操作的出现,也很大程度上改变了开发者对于Java的繁琐的操作的印象,从此,Java也走向了函数式编程的道路! 1 流的创建 1.1 流的创建方法 既然需要聊聊流的操作,那么,首先还是先看看怎么创建流. 创建流的方法有三种,分别是:Stream.of().Stream.iterate().Stream.generate(),然后,分别看一下这三个方法的声明. static <T> Stream<T> of

  • JDK1.8新特性Stream流式操作的具体使用

    一. 前言 随着Java的发展,越来越多的企业开始使用JDK1.8 版本.JDK1.8 是自 JDK1.5之后最重要的版本,这个版本包含语言.编译器.库.工具.JVM等方面的十多个新特性.本次文章将着重学习Stream. Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找.过滤和映射数据等操作.使用Stream API 对集合数据进行操作,就类似于使用SQ

  • java8新特性 stream流的方式遍历集合和数组操作

    前言: 在没有接触java8的时候,我们遍历一个集合都是用循环的方式,从第一条数据遍历到最后一条数据,现在思考一个问题,为什么要使用循环,因为要进行遍历,但是遍历不是唯一的方式,遍历是指每一个元素逐一进行处理(目的),而并不是从第一个到最后一个顺次处理的循环,前者是目的,后者是方式. 所以为了让遍历的方式更加优雅,出现了流(stream)! 1.流的目的在于强掉做什么 假设一个案例:将集合A根据条件1过滤为子集B,然后根据条件2过滤为子集C 在没有引入流之前我们的做法可能为: public cl

  • Java9新特性Stream流API优化与增强

    目录 1.Stream.takeWhile(Predicate) 2.Stream.dropWhile(Predicate) 3.StreamStream.iterate(T,Predicate,UnaryOperator) 4.StreamStream.ofNullable(T) 5.IntStream,LongStream和DoubleStream方法 我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还

  • Java8新特性Stream流实例详解

    什么是Stream流? Stream流是数据渠道,用于操作数据源(集合.数组等)所生成的元素序列. Stream的优点:声明性,可复合,可并行.这三个特性使得stream操作更简洁,更灵活,更高效. Stream的操作有两个特点:可以多个操作链接起来运行,内部迭代. Stream可分为并行流与串行流,Stream API 可以声明性地通过 parallel() 与sequential() 在并行流与顺序流之间进行切换.串行流就不必再细说了,并行流主要是为了为了适应目前多核机器的时代,提高系统CP

  • Java8中Stream流式操作指南之入门篇

    目录 简介 正文 1. 流是什么 2. 老板,上栗子 3. 流的操作步骤 4. 流的特点 5. 流式操作和集合操作的区别: 总结 简介 流式操作也叫做函数式操作,是Java8新出的功能 流式操作主要用来处理数据(比如集合),就像泛型也大多用在集合中一样(看来集合这个小东西还是很关键的啊,哪哪都有它) 下面我们主要用例子来介绍下,流的基操(建议先看下lambda表达式篇,里面介绍的lambda表达式.函数式接口.方法引用等,下面会用到) 正文 1. 流是什么 流是一种以声明性的方式来处理数据的AP

  • Java关于JDK1.8新特性的Stream流

    目录 Java 的Stream流 一.定义 二.操作的特征 三.代码示例 1.生成流 2.forEach 迭代 3.limit方法用于获取指定数量的流 4.map 5.sorted 6.并行(parallel)程序 7.Collectors 8.转化(将枚举类转成map) Java 的Stream流 一.定义 JDK1.8 中增加了Stream流,Stream流是一个来自数据源的元素队列并支持聚合操作.元素是特定类型的对象,形成一个队列,Java中的Stream并不会存储元素,而是按需计算数据源

  • Java8新特性Stream短路终端操作实例解析

    这篇文章主要介绍了Java8新特性Stream短路终端操作实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 传入一个谓词,返回传为boolean,如果符合条件,则直接结束流. 匹配所有 allMatch 任意匹配 anymMatch 不匹配 noneMatch 查找首个 findFirst 查找任意 findAny 匹配所有 allMatch /匹配所有 allMatch @Test public void allMatchTest()

  • Java8新特性Stream的完全使用指南

    什么是Stream Stream是Java 1.8版本开始提供的一个接口,主要提供对数据集合使用流的方式进行操作,流中的元素不可变且只会被消费一次,所有方法都设计成支持链式调用.使用Stream API可以极大生产力,写出高效率.干净.简洁的代码. 如何获得Stream实例 Stream提供了静态构建方法,可以基于不同的参数创建返回Stream实例 使用Collection的子类实例调用stream()或者parallelStream()方法也可以得到Stream实例,两个方法的区别在于后续执行

  • JDK1.6“新“特性Instrumentation之JavaAgent(推荐)

    简介 Java Agent是在JDK1.5以后,我们可以使用agent技术构建一个独立于应用程序的代理程序(即为Agent),用来协助监测.运行甚至替换其他JVM上的程序.使用它可以实现虚拟机级别的AOP功能. Agent分为两种,一种是在主程序之前运行的Agent,一种是在主程序之后运行的Agent(前者的升级版,1.6以后提供). JavaAgent的作用Agent给我们程序带来的影响.jpg 使用Agent-premain方法影响的程序效果图.jpg 使用Agent-agentmain方法

随机推荐