Java8新特性学习-Stream

栏目: 编程语言 · Java · 发布时间: 6年前

内容简介:Java 8 新增了一个新的抽象称为流Stream,个人感觉这个超级好用,尤其是业务开发,经常需要对数据列表进行处理的时候,用更少的代码、更优雅地实现功能。这个流式操作,更像是Linux中的管道命令'|',上一个操作的结果传送到下一个流程中继续处理,例如:在java代码实现
Java8新特性学习-Stream
Java8新特性学习-Stream:stuck_out_tongue_closed_eyes:

介绍

Java 8 新增了一个新的抽象称为流Stream,个人感觉这个超级好用,尤其是业务开发,经常需要对数据列表进行处理的时候,用更少的代码、更优雅地实现功能。

这个流式操作,更像是 Linux 中的管道命令'|',上一个操作的结果传送到下一个流程中继续处理,例如:

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+
复制代码

java 代码实现

String content = "hello,world,debug,the,world";
        List<String> list = Arrays.asList(content.split(","));

                List<String> filter = list.stream()
                .filter(temp -> temp.startsWith("w"))
                .map(temp -> temp.substring(0, 3))
                .collect(Collectors.toList());

        filter.forEach(System.out::print);
复制代码

什么是Stream

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

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

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

  • Pipelining :中间操作都会返回流对象本身。这样多个操作可以串联成一个管道。
  • 内部迭代 :以前对集合遍历都是通过Iterator或者For-Each的方式,显示的在集合外部进行迭代。Stream提供了内部迭代的方式,通过访问者模式(Visitor)实现。

生成流

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

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

这里要讲一下这两者的区别:

通俗点来说,一个是单线程、另一个是多线程。parallelStream是一个并行执行的流,通过默认的ForkJoinPool,可以提高多线程任务的速度。处理的过程会分而质之,将一个大任务切分成多个小任务,然后将结果合起来。(当然这也是一把双刃剑,在多线程的情况下,数据的并发访问需要关注,这也可以好好学一下,等之后再看吧~)

forEach

以前都是显示的使用循环,例如对一个集合进行打印: JDK7以前

for (int i = 0; i < list.size(); i++) {
    String temp = list.get(i);
    System.out.print(temp);
}

// 或者语法糖形式
for (String temp : list) {
    System.out.print(temp);
}
复制代码

JDK8之后

list.forEach(System.out::println);
复制代码

对比一下,发现只需要一行代码就能实现~ 如果想在forEach中进行自定义的操作,可以创建一个类,实现Consumer函数接口,传递进去使用~

map

map方法用于映射每个元素到对应的结果:

Car car1 = Car.create(Car::new, "小汽车1");
        Car car2 = Car.create(Car::new, "小汽车2");
        List<Car> carList = Lists.newArrayList(car1, car2);

        List<String> nameList = carList.stream().map(Car::getName).collect(Collectors.toList());
        // 还可以加入filter功能,先进行过滤,然后取出想要的字段组成新的列表
复制代码

Car类:

public class Car {
    
    private Integer id;

    private String name;

    public static Car create(final Supplier<Car> supplier, String name) {
        Car car = supplier.get();
        car.setName(name);
        return car;
    }

    public static void collide(final Car car) {
        System.out.println("Collided " + car.toString());
    }

    public void follow(final Car another) {
        System.out.println("Following the " + another.toString());
    }

    public void repair() {
        System.out.println("Repaired " + this.toString());
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Car{}" + Thread.currentThread().getId() + getName();
    }
}

复制代码

filter

如其名,filter就是用来过滤的,根据特定的条件来过滤元素:

List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);

        long count = ints.stream().filter(number -> number > 10).count();
        System.out.println(count);

复制代码

上面的例子是用来过滤出整数列表中,值大于10的数量。

limit

用来获取指定数量的流(类似于 MySQL 中的limit):

public void limitTest() {
        List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
        ints.stream().limit(5).forEach(System.out::println);
    }
复制代码

sorted

用来对流进行排序,类似于Collections.sort(list, Comparator);

List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
        ints.sort(Comparator.naturalOrder());

        Car car1 = Car.create(Car::new, "小汽车1");
        Car car2 = Car.create(Car::new, "小汽车2");
        List<Car> carList = Lists.newArrayList(car1, car2);
        // 可以自定义 排序 的字段,如果需要更复杂的排序规则,可以在lambda中的statement进行编写
        carList.sort(Comparator.comparing(Car::getName));
复制代码

Collectors

Collectors类实现了很多规约操作,例如将流转换成集合和聚合元素。(一般用Collectors.toList()就够了)

//例如在一组对象中或者主键ID的列表可以这样写
public void collectorsTest() {
        List<Car> carList = Lists.newArrayList();
        // 省略构建参数,获取列表中的主键ID列表
        List<Integer> ids = carList.stream().map(Car::getId).collect(Collectors.toList());
    }

复制代码

统计statistics

这个功能比较少用,还是学习记录一下吧。

public void statisticsTest() {
        List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
        IntSummaryStatistics statistics = ints.parallelStream().mapToInt(x -> (int) x).summaryStatistics();
        System.out.println("最大值 : " + statistics.getMax());
        System.out.println("最小值 :" + statistics.getMin());
        System.out.println("平均值 :" + statistics.getAverage());
        System.out.println("总和 : " + statistics.getSum());
        System.out.println("数量 :" + statistics.getCount());
    }
复制代码

完整的测试代码

package com.example.demo;

import com.example.demo.test.Car;
import com.google.common.collect.Lists;
import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author JingQ at 2019/1/31
 */
public class JDK8StreamTest {

    @Test
    public void buildStreamTest() {
        String content = "hello,world,debug,the,world";
        List<String> list = Arrays.asList(content.split(","));

        List<String> filter = list.stream()
                .filter(temp -> temp.startsWith("w"))
                .map(temp -> temp.substring(0, 3))
                .collect(Collectors.toList());
        filter.forEach(System.out::print);
    }

    @Test
    public void forEachTest() {
        String content = "hello,world,debug,the,world";
        List<String> list = Arrays.asList(content.split(","));

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


    @Test
    public void mapTest() {

        Car car1 = Car.create(Car::new, "小汽车1");
        Car car2 = Car.create(Car::new, "小汽车2");
        List<Car> carList = Lists.newArrayList(car1, car2);

        List<String> nameList = carList.stream().map(Car::getName).collect(Collectors.toList());
        // 还可以加入filter功能,先进行过滤,然后取出想要的字段组成新的列表
    }

    /**
     * filter过滤
     */
    @Test
    public void filterTest() {
        List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);

        long count = ints.stream().filter(number -> number > 10).count();
        System.out.println(count);
    }

    /**
     * limit 限制数量
     */
    @Test
    public void limitTest() {
        List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
        ints.stream().limit(5).forEach(System.out::println);
    }

    @Test
    public void sortedTest() {
        List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
        ints.sort(Comparator.naturalOrder());

        Car car1 = Car.create(Car::new, "小汽车1");
        Car car2 = Car.create(Car::new, "小汽车2");
        List<Car> carList = Lists.newArrayList(car1, car2);
        // 可以自定义排序的字段,如果需要更复杂的排序规则,可以在lambda中的statement进行编写
        carList.sort(Comparator.comparing(Car::getName));
    }

    @Test
    public void collectorsTest() {
        List<Car> carList = Lists.newArrayList();
        // 省略构建参数,获取列表中的主键ID列表
        List<Integer> ids = carList.stream().map(Car::getId).collect(Collectors.toList());
    }

    @Test
    public void statisticsTest() {
        List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9);
        IntSummaryStatistics statistics = ints.parallelStream().mapToInt(x -> (int) x).summaryStatistics();
        System.out.println("最大值 : " + statistics.getMax());
        System.out.println("最小值 :" + statistics.getMin());
        System.out.println("平均值 :" + statistics.getAverage());
        System.out.println("总和 : " + statistics.getSum());
        System.out.println("数量 :" + statistics.getCount());
    }
}


复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Introduction to Graph Theory

Introduction to Graph Theory

Douglas B. West / Prentice Hall / 2000-9-1 / USD 140.00

For undergraduate or graduate courses in Graph Theory in departments of mathematics or computer science. This text offers a comprehensive and coherent introduction to the fundamental topics of graph ......一起来看看 《Introduction to Graph Theory》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试