Stream流

Stream流

JDK1.8之后出现的,关注的是做什么而不是怎么做。Stream流和IO流是两个不一样的东西,IO流主要用来读写,而Stream主要用来对集合和数组进行一些简化操作。比如要对一个集合的元素进行遍历,之前的for循环,循环仅仅是一个方式,而不是目的。

现在要对一个集合进行过滤再输出,第一次过滤条件长度 > 3, 第二次过滤条件 包含“a”,之后输出。

package cn.zhuobo.day16.aboutStream;

import java.util.ArrayList;
import java.util.List;

public class Demo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaaa");
        list.add("aabb");
        list.add("bbbb");
        list.add("bbbb");
        list.add("ccbb");
        // 两次过滤,一次输出,三个for循环
        List<String> list1 = new ArrayList<>();
        for (String s : list) {
            if(s.length() > 3) {
                list1.add(s);
            }
        }
        List<String> list2 = new ArrayList<>();
        for (String s : list1) {
            if(s.contains("a")) {
                list2.add(s);
            }
        }
        List<String> list3 = new ArrayList<>();
        for (String s : list2) {
            System.out.println(s);
        }
        
        list.stream()
                .filter(s -> s.length() > 3)
                .filter(s -> s.contains("a"))
                .forEach(s -> System.out.println(s));

    }
}
+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

以上流转换的代码为

List<Integer> transactionsIds = 
widgets.stream()
             .filter(b -> b.getColor() == RED)
             .sorted((x,y) -> x.getWeight() - y.getWeight())
             .mapToInt(Widget::getWeight)
             .sum();

1、获取流的两种方式

  • 所有的单列集合Collection集合都可以通过默认方法stream获取流
  • Stream接口的静态方法of可以获取数组对应的流
    package cn.zhuobo.day16.aboutStream;

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

    public class Demo02GetStream {

        // 单列集合转化为流
        public static void main(String[] args) {
            List<String> list1 = new ArrayList<>();
            Stream<String> stream1 = list1.stream();

            Set<String> list2 = new HashSet<>();
            Stream<String> stream2 = list2.stream();

            Map<String, String> map = new HashMap<>();
            Set<String> keyset = map.keySet();
            Stream<String> stream3 = keyset.stream();

            Collection<String> values = map.values();
            Stream<String> stream4 = values.stream();


            //Set<map.Entry<String, String>> entries = map.entrySet();
            Set<Map.Entry<String, String>> entries1 = map.entrySet();

            Stream<Integer> stream5 = Stream.of(1, 2, 3, 4, 5);
            Integer[] arr = {1, 2, 3, 4};
            Stream<Integer> stream6 = Stream.of(arr);

        }
    }

2、Stream的常用方法

方法:
void forEach(Comsumer<? super T> action) 参数是函数式接口,用来遍历流中的数据,是一个终结方法(返回值不是流),遍历之后就不能继续调用Stream的其他方法
Stream filter(Predicate<? super T> predicate) 参数是函数式接口,传递Lambda表达式进行过滤,非终结方法,遍历之后可以继续调用其他Stream的方法
Stream map(Function< ? super T, ? extends R> mapper) 将流中的元素映射到另一个流中,该接口的参数是一个Function函数式接口,可以将当前流的T类型数据转换为另一个流的R类型数据
long count() 用于统计Stream流中元素的个数,返回值是long,是一个终结方法,不能再继续调用流的其他方法。
Stream limit(long maxSize) 截取流的前MaxSize个元素,生成新的流,并返回
Stream skip(long n) 跳过前n个,返回截掉n个元素的流,跳过全部,就返回长度为0的流
static Stream concat(Stream<? extends T> a, Stream<? extends T> b) 将两个流,合并为一个流,这是一个静态方法。

Stream流是一个管道流,是一次性使用的,也就是当Stream调用一个方法之后,这个流就会被关闭,将数据转移到下一流。当想用这个关闭的流再次调用方法时,就会抛出java.lang.IllegalStateException: stream has already been operated upon or closed异常。

Stream<String> stream = Stream.of("猪八戒", "蜘蛛侠", "齐天大圣", "李太白", "成吉思汗");

// 在这里,stream调用完方法forEach之后就已经被关闭了,数据转移到了stream1上
//stream.forEach(name -> System.out.println(name));
// filter方法
Stream<String> stream1 = stream.filter((String name) -> {
    return name.length() > 3;
});

方法展示

package cn.zhuobo.day16.aboutStream;

import java.util.stream.Stream;

public class StreamMothod {
    public static void main(String[] args) {
        // forEach
        Stream<String> stream = Stream.of("猪八戒", "蜘蛛侠", "齐天大圣", "李太白", "成吉思汗");
        //stream.forEach(name -> System.out.println(name));

        // filter方法
        Stream<String> stream1 = stream.filter((String name) -> {
            return name.length() > 3;
        });
        stream1.forEach(name -> System.out.println(name));

        // map方法
        Stream<String> stringStream = Stream.of("1", "2", "3", "4");
        Stream<Integer> integerStream = stringStream.map((str) -> Integer.parseInt(str));
        integerStream.forEach(num -> System.out.println(num));


//        count方法
        Integer[] arr = {1, 2, 3, 4, 5, 6, 7};
        Stream<Integer> stream2 = Stream.of(arr);
        System.out.println(stream2.count());

        // limit方法
        Stream<String> stringStream1 = Stream.of("aaa", "bbb", "ccc", "ddd", "eee");
        stringStream1.limit(3).forEach(str -> System.out.println(str));

        // skip方法
        Stream<String> stringStream2 = Stream.of("aaa", "bbb", "ccc", "ddd", "eee");
        stringStream2.skip(3).forEach(str -> System.out.println(str));

        // concat方法
        Stream<String> stringStream3 = Stream.of("aaa", "bbb", "ccc", "ddd", "eee");
        Stream<String> stringStream4 = Stream.of("猪八戒", "蜘蛛侠", "齐天大圣", "李太白", "成吉思汗");
        Stream.concat(stringStream4, stringStream3).forEach(str -> System.out.println(str));
    }
}
原文地址:https://www.cnblogs.com/zhuobo/p/10667017.html