美文网首页
2.java8新特性之Stream

2.java8新特性之Stream

作者: _少年不知愁 | 来源:发表于2018-04-03 22:58 被阅读0次

1.java8两大亮点之Stream

stream直译为流,但它与原IO流完全不同的概念。
简单地说:它是数据的渠道,用于操作数据源所生成的元素的序列,它可以像数据库中的数据一样,使用sql去操作。

  • stream自己不会存储元素
  • stream不会改变源对象,只是返回一个新的stream。
  • Stream操作是延迟执行的,需要执行的时候才会去给出结果。


    流式操作:创建Stream-中间操作-终止操作
    /**
     * 创建Stream
     */
    @Test
    public void test1() {
        //1.Collection系列集合 Stream()串行和parallelStream()并行
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();
        System.out.println(stream);

        //2.Arrays中的静态方法stream()获取数组流
        Student[] stus = new Student[10];
        Stream<Student> stream2 = Arrays.stream(stus);
        System.out.println(stream2);

        //3.Stream类中的静态方法of()
        Stream<String> stream3 = Stream.of("a", "b", "c");
        System.out.println(stream3);

        //4.无限流
        Stream.iterate(0, (x) -> x + 1).limit(10).forEach(System.out::println);
        //5.生成
        Stream.generate(() ->((Math.random())*100)).limit(10).forEach(System.out::println);

    }

输出结果:
java.util.stream.ReferencePipeline$Head@79be0360
java.util.stream.ReferencePipeline$Head@22a67b4
java.util.stream.ReferencePipeline$Head@57855c9a
88
6
55
67
91
17
91
9
6
14

(1)中间操作

(a)filter过滤,相当于sql中where age > 40

forEach(System.out::println)为终止操作,下面只是想看到操作结果
在forEach,其实没做任何操作,当执行到forEach终止操作才执行

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class Student {

    private Integer stuId;

    private String name;

    private Integer age;

    private Double matchScore;

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

    /**
     * filter过滤
     */
    @Test
    public void test1() {
        stus.stream().filter(x -> x.getAge() > 40).forEach(System.out::println);
    }
limit截断
    /**
     * limit截断
     */
    @Test
    public void test2(){
        stus.stream().limit(2).forEach(System.out::println);
    }
skip跳过
    /**
     * skip跳过
     */
    @Test
    public void test3(){
        stus.stream().skip(2).forEach(System.out::println);
    }
distinct去重
    /**
     * distinct去重
     */
    @Test
    public void test4() {
        stus.stream().distinct().forEach(System.out::println);
    }

(b)映射

map会转换成一个新对象
    /**
     * map映射
     */
    @Test
    public void test5() {
        List<String> a = Arrays.asList("abc", "cba", "bca");
        a.stream().map(x -> x.toUpperCase()).forEach(System.out::println);

        stus.stream().map(Student::getStuId).forEach(System.out::print);
    }

输出结果为:
ABC
CBA
BCA
112345

flatMap将多个流里元素加到同一个流中
   @Test
    public void test6() {
        List<String> a = Arrays.asList("abc", "cba", "bca");

        Stream<Stream<Character>> s = a.stream().map(TestLambda4::filterCharacter);
        s.forEach(x -> {
            x.forEach(System.out::println);
        });

        //直接使用flatMap
        Stream<Character> s1 =  a.stream().flatMap(TestLambda4::filterCharacter);
        System.out.println("--------------------------");
        s1.forEach(System.out::println);
    }

    public static Stream<Character> filterCharacter(String str) {
        List<Character> list = new ArrayList<>();
        for (Character c : str.toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }

结果输出一样。

(c)排序

    /**
     * 排序
     */
    @Test
    public void test8() {
        List<String> a = Arrays.asList("bb", "cc", "dd", "aa");

        //自然排序(comparable)
        a.stream().sorted().forEach(System.out::println);

        //定制排序()
        stus.stream().sorted((x, y) -> x.getMatchScore().compareTo(y.getMatchScore())).forEach(System.out::println);
    }

(2)终止操作

(a)查找与匹配

获取数据

    @Test
    public void test1() {
        //是否匹配所有元素返回true
        boolean b1 = stus.stream().allMatch(x -> x.getAge() > 19);
        System.out.println(b1);

        //只要有一个匹配返回true
        boolean b2 = stus.stream().anyMatch(x -> x.getAge() > 43);
        System.out.println(b2);

        //没有匹配所有元素(都不符合返回true)
        boolean b3 = stus.stream().noneMatch(x -> x.getAge() > 43);
        System.out.println(b3);

        //取第一条,因为结果可能为空,可以用Optiona接,可以用方法get获取
        Optional<Student> op1 = stus.stream().sorted((x, y) -> Double.compare(x.getMatchScore(), y.getMatchScore())).findFirst();
        System.out.println(op1.get());

        //随机取一条
        Optional<Student> op2 = stus.parallelStream().findAny();
        System.out.println(op2.get());
    }

统计,与数据库中的聚合函数类似

    @Test
    public void test2() {
        //相当于sql中count
        Long num1 = stus.stream().count();
        System.out.println(num1);

        //max或者min一样
        Optional<Student> op1 = stus.stream().max((x, y) -> Double.compare(x.getMatchScore(), y.getMatchScore()));
        System.out.println(op1.get());

        System.out.println(stus.stream().map(Student::getMatchScore).min(Double::compare).get());
    }
(b)归约
  /**
     * 归约
     * reduce(T identy, BinaryOperaator)/reduce(BinaryOperaator)
     * 可以将流中元素反复结合起来,得到一个新的值
     */
    @Test
    public void test3() {
        List<Integer> lis = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        //算总和
        Integer sum = lis.stream().reduce(0, (x, y) -> x + y);
        System.out.println(sum);

        /**
         * 统计总分
         * 流行map-reduce模式,大数据里面
         */
        Double sum1 = stus.stream().map(Student::getMatchScore).reduce(Double::sum).get();
        System.out.println(sum1);
    }

(c)收集

    /**
     * collect--将流转换成其他方式。接收一个Collector接口的实现,用于给stream中元素做汇总的方法
     */
    @Test
    public void test4() {
        //
        List<String> lis = stus.stream().map(Student::getName).collect(Collectors.toList());
        lis.forEach(System.out::println);

        HashSet<String> hs = stus.stream().map(Student::getName).collect(Collectors.toCollection(HashSet::new));
        hs.forEach(System.out::println);

        //会报错 Duplicate key 100.0,
        Map<Integer, Double> hs2 = stus.stream().collect(Collectors.toMap(Student::getStuId, Student::getMatchScore));
        Map<Integer, Student> hs1 = stus.stream().collect(Collectors.toMap(Student::getStuId, Function.identity(), (key1, key2) -> key2));
        System.out.println(hs1);
    }
(d)数据库中聚合函数操作
 @Test
    public void test5() {
        //总数
        Long count = stus.stream().collect(Collectors.counting());
        System.out.println(count);

        //平均值
        Double avg = stus.stream().collect(Collectors.averagingDouble(Student::getMatchScore));
        System.out.println(avg);

        //总和
        Double sum = stus.stream().collect(Collectors.summingDouble(Student::getMatchScore));
        System.out.println(sum);

        //最大值
        Optional<Student> max = stus.stream().collect(Collectors.maxBy((x, y) -> Double.compare(x.getMatchScore(), y.getMatchScore())));
        System.out.println(max.get().getMatchScore());

        //最小值
        Optional<Student> min = stus.stream().collect(Collectors.minBy((x, y) -> Double.compare(x.getMatchScore(), y.getMatchScore())));
        System.out.println(min.get().getMatchScore());


        //获取以上所有
        DoubleSummaryStatistics dss = stus.stream().collect(Collectors.summarizingDouble(Student::getMatchScore));

    }

(e)分组,分区以及字符串拼接
   /**
     * 分组
     */
    @Test
    public void test6() {
        //根据年龄分组
        Map<Integer, List<Student>> map = stus.stream().collect(Collectors.groupingBy(Student::getAge));
        System.out.println(map);

        //多级分组 先年龄分在按 分数分
        Map<Integer, Map<String, List<Student>>> map1 = stus.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(
                (e) -> {
                    if (e.getMatchScore() > 80) {
                        return "优秀";
                    } else {
                        return "及格";
                    }
                }
        )));
        System.out.println(map1);

        //分区
        Map<Boolean, List<Student>> map2 = stus.stream().collect(Collectors.partitioningBy(e -> e.getMatchScore() > 80));
        System.out.println(map2);

        //文件拼接,常用于文件的拼接
        String s = stus.stream().map(x -> x.getStuId() + "|" + x.getName()).collect(Collectors.joining("\n", "+++", "---"));
        System.out.println(s);

    }

2.Optional容器类

(1)一个容器类,代表一个值存在或者不存在(null),为了避免控制异常,用起来十分方便。
   @Test
    public void test1() {
        //创建一个Optional实例
        Optional<Student> op1 = Optional.of(new Student("2"));
        System.out.println(op1);

        // Optional.of(null); NullPointerException

        //创建一个空对象
        Optional<Student> op2 = Optional.empty();
        System.out.println(op2);

        //有值则创建一个Optional实例,无创建一个空对象
        Optional<String> op3 = Optional.ofNullable(null);
        System.out.println(op3);

        //optional 提供了一个方法 isPresent判断是否有值
        if(op3.isPresent()){
            System.out.println(op3);
        }
    }

输出结果:
Optional[Student(stuId=null, name=2, age=null, matchScore=null)]
Optional.empty
Optional.empty

(2)实践应用

常常会遇到如果为null的时候给一个默认值

    @Test
    public void test2() {
        //项目中经常会用到 有则干嘛, 无责干嘛 if else
        Optional<String> op1 = Optional.ofNullable(new String("1"));
        Student st = new Student("test");
        String op = Optional.ofNullable(st.getName()).orElse("@");
        System.out.println(op);

        Optional<Student> op2 = Optional.ofNullable(new Student("mayun"));
        Optional<Student> op3 = Optional.empty();

        Student s1 = op2.orElseGet(() -> new Student("mahuateng"));
        Student s2 = op3.orElseGet(() -> new Student("mahuateng"));
        System.out.println(s1 + "++++" + s2);
    }

输出结果:
test
Student(stuId=null, name=mayun, age=null, matchScore=null)++++Student(stuId=null, name=mahuateng, age=null, matchScore=null)
欢迎大家一起来补充修正!!!

相关文章

  • 2.java8新特性之Stream

    1.java8两大亮点之Stream stream直译为流,但它与原IO流完全不同的概念。简单地说:它是数据的渠道...

  • 新特性之 Stream流

    1.Stream流式思想 当使用一个流的时候,通常包括三个基本步骤:获取一个数据源(source)→ 数据转换→执...

  • Java新特性之-stream

    Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。 熟悉linux sh...

  • Stream流

    Stream流 java8新特性 Stream定义 A sequence of elements supporti...

  • java8 ---Stream

    1. 集合的Lambda --forEach 使用 1.1 集合的排序实例 2.Java8 的Stream 的使...

  • Java 8 新特性之 Stream

    新的 java.util.stream 包中的类提供了一个Stream API,以支持对元素流的函数式操作。 St...

  • Redis拓展及5.0新特性

    Redis5.0新特性 1.Stream 特性 消费者独立消费: 创建消费组 stream 在每个消费者结构中保存...

  • java 8 stream 流详细教程

    1 基本特性 Java8的API中添加了一个新的特性: 流,即stream。stream是将数组或者集合的元素视为...

  • Java | Stream

    简介 Stream流 是 JDK1.8 加入的新特性,Stream流跟I/O流不同,Stream流用于操作数据源(...

  • MongoDB Change Stream初体验

    Change Stream是MongoDB从3.6开始支持的新特性。这个新特性有哪些奇妙之处,会给我们带来什么便利...

网友评论

      本文标题:2.java8新特性之Stream

      本文链接:https://www.haomeiwen.com/subject/rfdocftx.html