Stream流

什么是Stream流?

        Stream是Java 8 API添加的一个新的抽象,称为Stream流,以一种声明性方式处理数据集合(侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式)。流不是集合元素,它不是数据结构并不保存数据,它的主要目的在于计算。

流程:

        1、将集合转换为Stream流(或者创建流)。

        2、操作Stream流(中间操作,终端操作)。

Stream流的创建:

        1、Stream创建:

        Stream<Integer> stream1 = Stream.of(1,2,3,4,5);

        2、Collection集合创建(应用中最常用的一种)

        List<Integer> integerList = new ArrayList<>();
        integerList.add(1);
        integerList.add(2);
        integerList.add(3);
        Stream<Integer> listStream = integerList.stream();

        3、Array数组创建:

        通过Arrays.stream方法生成流,并且该方法生成的流是数值流【即IntStream】而不是 Stream。注:使用数值流可以避免计算过程中拆箱装箱,提高性能。Stream API提供了mapToInt、mapToDouble、mapToLong三种方式将对象流【即Stream 】转换成对应的数值流,同时提供了boxed方法将数值流转换为对象流。

         int[] intArr = {1, 2, 3, 4, 5};

         IntStream arrayStream = Arrays.stream(intArr);

        4、文件创建:

        通过Files.line方法得到一个流,并且得到的每个流是给定文件中的一行。

        Stream<String> fileStream = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());

        5、函数创建:

                iterator

                Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(5);

                generator

                Stream<Double> generateStream = Stream.generate(Math::random).limit(5);

操作符

        流的操作符主要分两种:中间操作符、终端操作符

        中间操作符:

                通常对于Stream的中间操作,可以视为是源的查询,并且是懒惰式的设计,对于源数据进行的计算只有在需要时才会被执行,与数据库中视图的原理相似。一个流可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。

        常见的中间操作符:

流方法说明范例
filter用于通过设置的条件过滤出元素

过滤出元素    
List strings = Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,"", “jkl”);

List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

map接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

List mapped = strings.stream().map(str->str+"-itcast").collect(Collectors.toList());

distinct返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);
sorted返回排序后的流

List strings1 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

List sorted1 = strings1.stream().sorted().collect(Collectors.toList());

limit会返回一个不超过给定长度的流

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

List limited = strings.stream().limit(3).collect(Collectors.toList());

skip返回一个扔掉了前n个元素的流

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

List skiped = strings.stream().skip(3).collect(Collectors.toList());

flatMap使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

Stream flatMap = 

strings.stream().flatMap(Java8StreamTest::getCharacterByString);

peek对元素进行遍历处理

List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);

strings .stream().peek(str-> str + "a").forEach(System.out::println);

        终端操作符:

                Stream流执行完终端操作之后,无法再执行其他动作,否则会报状态异常,提示该流已经被执行操作或者被关闭,想要再次执行操作必须重新创建Stream流。一个流有且只能有一个终端操作,当这个操作执行后,流就被关闭了,无法再被操作,因此一个流只能被遍历一次,若想在遍历需要通过源数据在生成流。

        常见的终端操作符:

流方法说明范例
collect收集器,将流转换为其他形式

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

Set set = strings.stream().collect(Collectors.toSet());

List list = strings.stream().collect(Collectors.toList());

Map<String, String> map = strings.stream().collect(Collectors.toMap(v ->v.concat("_name"), v1 -> v1, (v1, v2) -> v1));

forEach遍历流

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”,

“jkl”);strings.stream().forEach(s -> out.println(s));

findFirst返回第一个元素

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

Optional first = strings.stream().findFirst();

findAny将返回当前流中的任意元素

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

Optional any = strings.stream().findAny();

count返回流中元素总数

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

long count = strings.stream().count();

sum求和int sum = userList.stream().mapToInt(User::getId).sum();
max最大值

int max =

userList.stream().max(Comparator.comparingInt(User::getId)).get().getId();

min最小值

int min =

userList.stream().min(Comparator.comparingInt(User::getId)).get().getId();

anyMatch检查是否至少匹配一个元素,返回boolean

List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

boolean b = strings.stream().anyMatch(s -> s == “abc”);

allMatch检查是否匹配所有元素,返回boolean

List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

boolean b = strings.stream().allMatch(s -> s == “abc”);

noneMatch检查是否没有匹配所有元素,返回boolean

List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

boolean b = strings.stream().noneMatch(s -> s == “abc”);

reduce可以将流中元素反复结合起来,得到一个值

List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);

Optional reduce = strings.stream().reduce((acc,item) -> {return acc+item;});if(reduce.isPresent())out.println(reduce.get());

Collect收集:

        Collector:结果收集策略的核心接口,具备将指定元素累加存放到结果容器中的能力;并在Collectors工具中提供了Collector接口的实现类。

1、toList:

        将用户ID存放到List集合中

        List<Integer> idList = userList.stream().map(User::getId).collect(Collectors.toList()) ;

2、toMap:

        将用户ID和Name以Key-Value形式存放到Map集合中

        Map<Integer,String> userMap =         userList.stream().collect(Collectors.toMap(User::getId,User::getName));

3、toSet:

        将用户所在城市存放到Set集合中

        Set<String> citySet = userList.stream().map(User::getCity).collect(Collectors.toSet());

4、counting:

        符合条件的用户总数

        long count = userList.stream().filter(user -> user.getId()>1).collect(Collectors.counting());

5、summingInt:

        对结果元素即用户ID求和

        Integer sumInt = userList.stream().filter(user -> user.getId()>2).collect(Collectors.summingInt(User::getId)) ;

6、minBy:

        筛选元素中ID最小的用户

        User maxId = userList.stream().collect(Collectors.minBy(Comparator.comparingInt(User::getId))).get() ;

7、joining:

        将用户所在城市,以指定分隔符链接成字符串;

        String joinCity = userList.stream().map(User::getCity).collect(Collectors.joining("||"));

8、groupingBy:

        按条件分组,以城市对用户进行分组;

        Map<String,List<User>> groupCity = userList.stream().collect(Collectors.groupingBy(User::getCity));

orElse(null):

        表示如果一个都没找到,返回null(orElse()中可以塞默认值,如果找不到就会返回orElse()中设置的默认值)。

orElseGet(null):

        表示如果一个都没找到返回null(orElseGet()中可以塞默认值,如果找不到就会返回orElseGet()中设置的默认值)。

orElse()和orElseGet()的区别:

        当传入的对象为null时,orElse也会执行里面的方法,orElseGet也会执行。

        当传入对象不为空,orElse会执行,但是orElseGet不会执行。

        范例:

orElse():

执行结果:

orElseGet():

 

执行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值