java8——流式编程

流式编程

一、流支持

java中代码那么多,如何简单的让大多数类库中的类都引入流的概念呢?
Java 8 采用的解决方案是:在接口中添加被 default(默认)修饰的方法。通过这种方案,设计者们可以将流式(stream)方法平滑地嵌入到现有类中。流方法预置的操作几乎已满足了我们平常所有的需求。流操作的类型有三种:创建流,修改流元素(中间操作, Intermediate Operations),消费流元素(终端操作, Terminal Operations)。最后一种类型通常意味着收集流元素(通常是汇入一个集合)。

二、创建流

package com.gykalc.jdk8.stream;

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

public class StreamTest1 {
    public static void main(String[] args) {
        // 创建流的方式

        /**
         * 创建一个无限大小的流,通常使用limit去限制大小
         * @params Object seed:表示传入的第一个值
         * @params UnaryOperator:是一个函数式接口,继承了Function,传入一个值,返回一个值,两个值类型相同
         */
        Stream.iterate(1, i -> i + 2).limit(5).forEach(System.out::print);// 13579

        Random random = new Random(47);
        /**
         * 方法返回一个无限连续的无序流,用来生成随机流或常量流,也可以用limit限制大小
         */
        Stream.generate(() -> random.nextInt(20)).limit(5).forEach(System.out::println);


        /**
         * 通过一个可变参数,传入多个值创建的一个流对象
         */
        Stream.of(1, 3, 5, 7, 9).forEach(System.out::println);

        /**
         * 创建一个空的流对象
         */
        Stream.empty();
    }

}

除此之外,每个集合都可以通过调用 stream() 方法来产生一个流。代码示例:

import java.util.*;
import java.util.function.Function;
import java.util.stream.Stream;

public class Main {
}

class CollectionToStream {
    public static void main(String[] args) {
        List<Bubble> bubbleList = Arrays.asList(new Bubble(1), new Bubble(2), new Bubble(3));
        System.out.println(bubbleList.stream()
            .mapToInt(b -> b.i)
            .sum());

        Set<String> w = new HashSet<>(Arrays.asList("It's a wonderful day for pie!"));
        w.stream().
                map(x -> x + " ")
                .forEach(System.out::println);


        Map<String, Double> m = new HashMap<>();
        m.put("pi", 3.14159);
        m.put("e", 2.718);
        m.put("phi", 1.618);
        m.entrySet().stream()
            .map(e -> e.getKey() + ": " + e.getValue())
            .forEach(System.out::println);
    }
}

class Bubble {
    public final int i;

    public Bubble(int n) {
        i = n;
    }

    @Override
    public String toString() {
        return "Bubble{" +
                "i=" + i +
                '}';
    }

    private static int count = 0;
    public static Bubble bubbler() {
        return new Bubble(count++);
    }
}

在这里插入图片描述

三、函数式接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
还有很多这种函数式接口,我们可以进入源代码中查看他的作用

四、Optional的作用

主要用来避免空指针异常

package com.gykalc.jdk8.stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class StreamTest1 {
    public static void main(String[] args) {
        // 创建一个空的Optional
        Optional<Object> empty = Optional.empty();
        // 创建一个Optional对象
        Optional<Integer> integer = Optional.of(2);
        // 创建一个包含允许是空元素的Optional对象
        Optional<Object> o = Optional.ofNullable(null);
        // 判断Optional中的元素是否为null
        System.out.println(empty.isPresent());
        System.out.println(integer.isPresent());
        System.out.println(o.isPresent());

        // orElse:如果Optional中的元素为空,则返回other参数
        System.out.println(integer.orElse(1));
        System.out.println(empty.orElse(1));
        System.out.println(o.orElse("1"));

        // get:获取Optional中的元素,如果为null,会报错
//        empty.get();

        // ifPresent:如果Optional的元素不为空,就执行里面的函数或者lambda
        empty.ifPresent(System.out::println);
        integer.ifPresent(System.out::println);
        o.ifPresent(System.out::println);

        List<Integer> list = new ArrayList<>(Arrays.asList(1, 3, 5, 7, 9));
        Optional<List<Integer>> optionalList = Optional.of(list);
        // flatMap:flatMap中的函数,返回值必须是Optional<T>类型的
        Optional<Integer> integer1 = optionalList.flatMap(param -> param.stream().filter(i -> i > 10).findFirst());
        System.out.println(integer1);
        // map:map中的函数,返回值是任意类型,但是返回之后会被map包装为一个optional对象
        Optional<Integer> integer2 = optionalList.map(param -> param.stream().filter(i -> i > 10).findFirst().orElse(null));
        System.out.println(integer2);
    }

}

五、使用流操作集合,完成以前的复杂操作

package com.gykalc.jdk8.stream;


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

public class StreamTest1 {
    public static void main(String[] args) {
        Student student1 = new Student("zhangsan", 100, 20);
        Student student2 = new Student("lisi", 90, 21);
        Student student3 = new Student("wangwu", 91, 22);
        Student student4 = new Student("zhaoliu", 80, 21);
        Student student5 = new Student("zhangsan", 92, 20);
        List<Student> studentList = new ArrayList<>(Arrays.asList(student1, student2, student3, student4, student5));
        /**
         * 流操作中,返回Stream对象的都是中间操作,懒加载。
         * 不返回Stream对象的是终止操作,会立即执行所有操作
         * 而且在流中,一个流不能重复被操作,因为一旦操作流,就
         * 会生成一个新的流对象
         * map:将studentList中所有元素都遍历一遍,
         *  并执行某个函数操作,他是中间操作,懒加载的,
         *  一定要遇到终止操作才会执行
         *
         *  使用map,将zhangsan的名字改成"张三"
         */
        studentList.stream().map(stu -> {
            if (stu.getName().equals("zhangsan")) {
                stu.setName("张三");
            }
            return stu;
        }).forEach(System.out::println);
        // 多重集合
        List<List<Integer>> lists = Arrays.asList(Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6));
        /**
         * 如果我们想把多重集合的值,全部都转移到一个集合中,可以使用flatmap
         */
        List<Integer> integerList = lists.stream().flatMap(l -> l.stream()).collect(Collectors.toList());
        System.out.println(integerList);
        /**
         * 我们想要把所有的学生名称存到一个集合中,也可以使用flatmap
         */
        List<String> nameList = studentList.stream().flatMap(stu -> Stream.of(stu.getName())).collect(Collectors.toList());
        System.out.println(nameList);

        /**
         * 假如我们想要给学生按名称进行分组,并保存到一个map中
         * 结构为:Map<String, List<Student>>
         * 方法一:
         */
        HashMap<String, List<Student>> stringListHashMap1 = studentList.stream().collect(HashMap<String, List<Student>>::new,
                (hashMap, student) -> {
                    if (hashMap.containsKey(student.getName())) {
                        hashMap.get(student.getName()).add(student);
                    } else {
                        hashMap.put(student.getName(), new ArrayList<>(Arrays.asList(student)));
                    }
                }, (stringListHashMap, stringListHashMap2) -> stringListHashMap.putAll(stringListHashMap));
        System.out.println(stringListHashMap1);

        /**
         * 假如我们想要给学生按名称进行分组,并保存到一个map中
         * 结构为:Map<String, List<Student>>
         * 方法二:
         */
        Map<String, List<Student>> stringListHashMap2 = studentList.stream().collect(Collectors.groupingBy(Student::getName));
        System.out.println(stringListHashMap2);

        /**
         * 假如我们想要给学生按名称进行分组获取成绩的平均值
         */
        Map<String, Double> stringDoubleMap = studentList.stream().collect(Collectors.groupingBy(Student::getName, Collectors.averagingDouble(Student::getScore)));
        System.out.println(stringDoubleMap);

        /**
         * 分区:分组的特殊情况,只存在true和false
         * 将分数大于90的和小于90的分区
         */
        Map<Boolean, List<Student>> booleanListMap = studentList.stream().collect(Collectors.partitioningBy(stu -> stu.getScore() > 90));
        System.out.println(booleanListMap);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值