阅读 36

Java 流使用(stream)

流是什么

1、jdk1.8引入的新成员,以声明方式处理集合数据 2、将基础操纵链接起来,完成复杂点的操作 3、提供透明的并行处理

流的简介

从支持数据处理操作生成的元素序列

 解释下这句话中粗体的意思
    元素序列:与集合一样,流也提供一个接口可以访问特定元素类型的一组有序值

     源:源是为流提供数据的源头,比如集合,数组
     数据处理操作:支持类似于数据库的操作,以及一些函数式编程语言的操作
复制代码

流与集合区别

1、时间与空间: 集合比如是一个dvd的光碟,流就像一个流媒体播放,不需要获取所有的电影数据帧,只需要获取当前的就可以。 这样来看集合就像空间元素的存储,而流就是时间维度的生成

定位: 集合面向存储,流面向计算

举例: 比如构建一个质数的集合,理论上是不可以的,因为质数无限大,如果构建一个质数流就可以,只需要在使用这个质数的时候实时的计算这个质数就可以

2、只能遍历一次

集合可以多次遍历,流只能遍历一次

3、外部迭代与内部迭代

流的组成

流的操作分类

流的使用

package gom.gc.guoshicheng.lambda.stream;

import org.junit.Before;
import org.junit.Test;

import java.util.*;

/**
 * 流使用测试类
 */
public class StreamOperator {


    List<String> strings;

    @Before
    public void init() {
        strings = new ArrayList<String>() {
            {
                add("java");
                add("java");
                add("C#");
                add("C#");
                add("C#");
                add("C#");
                add("python");
                add("python");
                add("python");
                add("c++");
                add("c++");
                add("c++");
                add("c++");
                add("c++");
            }
        };
    }

    /**
     * filter 使用: 过滤掉不符合断言判断的数据
     */
    @Test
    public void filterTest() {
        strings.stream()
                /**
                 * 满足这个条件 的留下来
                 */
                .filter(strings -> strings == "java")
                .forEach(item -> System.out.println(item));
    }

    /**
     * map使用: 将一个元素转换成另一个元素
     */
    @Test
    public void mapTest() {
        strings.stream()
                //map
                .map(strings -> strings.length() == 1 ? 1 : 2)
                .forEach(item -> System.out.println(item));
    }

    /**
     * flatMap使用: 将一个对象转换成流
     */
    @Test
    public void flatMapTest() {
        strings.stream()
                //map
                .flatMap(strings -> Arrays.stream(strings.split("")))
                .forEach(item -> System.out.println(item));
    }

    /**
     * peek使用:与forEach相似,但是不会销毁流 中间操作,这个操作完成后   流还可以使用
     */
    @Test
    public void peekTest() {
        strings.stream()
                //map 无状态操作 ,打印时  交替进行和 forEach
                .peek(strings -> System.out.println(strings))
                .forEach(item -> System.out.println(item));
    }

    /**
     * sort: 对流中元素排序,可以选择自然排序或着指定排序规则
     */
    @Test
    public void sortTest() {
        strings.stream()
                .peek(strings -> System.out.println(strings))
                .sorted(Comparator.comparing(String::length))
                .forEach(item -> System.out.println(item));
    }

    /**
     * distinct使用: 对流元素去重,有状态操作
     */
    @Test
    public void distinctTest() {
        strings.stream()
                ///如果list内是对象   使用lambda表达式   str -> str.getUserName
                .distinct()
                .forEach(item -> System.out.println(item));
    }

    /**
     * skip 跳过前几条记录
     */
    @Test
    public void skipTest() {
        strings.stream()
                .sorted()
                .skip(2)
                .forEach(item -> System.out.println(item));

    }

    /**
     * limit 取出前几条
     */
    @Test
    public void limitTest() {
        strings.stream()
                .sorted(Comparator.comparing(String::length))
                .limit(4)
                .forEach(item -> System.out.println(item));

    }

    /**
     * allMatch使用: 终端操作,短路操作: 所有元素匹配,返回true
     */
    @Test
    public void allMatchTest() {
        boolean match = strings.stream()
                .peek(System.out::println)
                .allMatch(strings -> strings.length() > 2);
        System.out.println(match);
    }

    /**
     * anyMatch使用: 任何元素匹配,返回true
     */
    @Test
    public void anyMatchTest() {
        boolean match = strings.stream()
                .peek(System.out::println)
                .anyMatch(strings -> strings.length() > 2);
        System.out.println(match);
    }

    /**
     * noneMatch 使用: 任何元素都不匹配,返回true
     */
    @Test
    public void noneMatchTest() {
        boolean match = strings.stream()
                .peek(System.out::println)
                .noneMatch(strings -> strings.length() > 2);
        System.out.println(match);
    }

    /**
     * findFirst 使用: 找到第一个元素
     *
     * findFirst与 findAny 区别,流并行上findAny 有可能返回的值不一致,如果串行上这两个返回的值没有区别
     */
    @Test
    public void findFirstTest() {
        Optional<String> match = strings.stream()
                .findFirst();
        System.out.println(match.get());
    }
    /**
     * findAny 使用: 找到任意元素
     */
    @Test
    public void findAnyTest() {
        Optional<String> match = strings.stream()
                .findAny();
        System.out.println(match.get());
    }

 /**
     * max 使用: 找到集合中最大值
     */
    @Test
    public void maxTest() {
        Optional<String> match = strings.stream()
                .max(Comparator.comparing(strings -> strings.length()));
        System.out.println(match.get());
    }
 /**
     * min 使用: 找到集合最小值
     */
    @Test
    public void minTest() {
        Optional<String> match = strings.stream()
                .min(Comparator.comparing(strings -> strings.length()));
        System.out.println(match.get());
    } /**
     * count 使用: 总条数
     */
    @Test
    public void countTest() {
        long count = strings.stream()
                .count();
        System.out.println(count);
    }


}

复制代码

流的构建

package gom.gc.guoshicheng.lambda.stream;

import org.junit.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 流的四种构建形式
 */
public class StreamConstructor {

    /**
     * 由数值直接构建流
     */
    @Test
    public void streamFromValue() {
        Stream<Integer> integerStream = Stream.of(1, 2, 23, 23, 21, 321, 321);
        integerStream.forEach(System.out::println);
    }

    /**
     * 通过数组构建流
     */
    @Test
    public void streamFromArray() {
        int[] numbers = {1, 2312, 321, 312, 412, 321};
        IntStream stream = Arrays.stream(numbers);
        stream.forEach(System.out::println);
    }

    /**
     * 通过文件生成流
     */
    @Test
    public void streamFromFile() throws IOException {
        Stream<String> stream = Files.lines(Paths.get("D:\\work\\source\\学习\\_996\\src\\" +
                "test\\java\\gom\\gc\\guoshicheng\\lambda\\" +
                "stream\\StreamConstructor.java"));
        stream.forEach(System.out::println);
    }

    /**
     * 通过函数生成流 (无限流)
     */
    @Test
    public void streamFromFunction() throws IOException {
//        Stream<Integer> stream = Stream.iterate(0, n -> n + 2);
        Stream stream = Stream.generate(Math::random);
        stream.forEach(System.out::println);
    }

}

复制代码

处理完数据 该收集数据了

收集器简介

预定义收集器功能

案例

package gom.gc.guoshicheng.lambda.stream;

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 常见预定义收集器使用
 */
public class StreamCollector {

    List<String> strings;

    @Before
    public void init() {
        strings = new ArrayList<String>() {
            {
                add("java");
                add("java");
                add("java");
                add("java");
                add("C#");
                add("C#");
                add("C#");
                add("C#");
                add("C#");
                add("python");
                add("python");
                add("python");
                add("python");
                add("python");
                add("java");
                add("java");
            }
        };
    }

    /**
     * 集合收集器
     */
    @Test
    public void toList() {
        List<String> collect = strings.stream()
                .filter(strings -> strings.length() > 3)
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 分组
     */
    @Test
    public void group() {
        Map<Integer, List<String>> collect = strings.stream()
                .filter(strings -> strings.length() > 3)
                .collect(Collectors.groupingBy(String::length));
        System.out.println(collect);
    }

    /**
     * 分区
     */
    @Test
    public void partition() {
        Map<Boolean, List<String>> collect = strings.stream()
                .collect(Collectors.partitioningBy(strings -> strings.toString().length() > 10));
        System.out.println(collect);
    }
}

复制代码

总结

希望在工作中遇到 stream操作 能灵活使用,这只是使用流的开始,再发掘更高效的使用方式吧

关注下面的标签,发现更多相似文章
评论