java8 Stream流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xyy1028/article/details/83692901

1.流操作

分为两大类:中间操作和终端操作,可以连接起来的流操作称为中间操作,关闭流的操作称为终端操作。


2.中间操作和终端操作

例如filter等中间操作会返回另一个流,除非流水线上触发一个终端操作,否则中间操作不会执行任何处理,它们很懒。这是因为中间操作一般都可以合并起来,在终端操作时一次性全部处理。

流的使用一般包括三个步骤:生成流,中间操作,终端操作

常用的中间操作:filter,map,limit,sorted,distinct

常用的终端操作:forEach,count,collect

3.流的特性

 3.1 流不是集合,也不是数据结构,其本身并不存储任何元素(或其地址值),流一个来自数据源的元素队列,它更像一个高级版本的         Iterator。原始的Iterator只能显式地一个一个遍历元素并对其执行某些操作,Stream可以过滤元素进行操作,Stream会隐式地         在内部进行遍历,做出相应的数据转换,但是只能单向的遍历一次

 3.2 使用stream流对集合元素或者数组元素操作时,源数据并不改变

 3.3 流只能遍历一次,用完之后就不存在了,只能重新创建流才能使用

 3.4 并行化:for循环性能 > parallelStream(并行流)性能 > Stream(普通流)性能 , parallelStream是一个并行执行的流,可以提高多线        程任务的速度

      parallelStream流的forEach是并行的,所以打印出的是乱序的,用forEachOrdered又变成并序的了

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        numbers.parallelStream().forEach(System.out::println);
        numbers.parallelStream().forEachOrdered(System.out::println);

      3.5 惰性:流的惰性与流的中间操作有关,流的中间操作将会为最终操作创建另一个流,但不会执行实际的处理,这有助于提升性              能

      3.6 短路行为:对中间操作进行短路操作,一旦满足条件流将会终止操作,分为有状态中间操作和无状态中间操作,无状态中间操作             性能更高

            有状态中间操作:distinct(),sort(),limit()

            无状态中间操作:filter(),map()

4.流常用操作

4.1获取流

      4.1.1 所有Collection集合都可以通过stream默认方法获取流

      4.1.2 将数组转成流

        double[] numbers = {1.1, 2.2,3.3,4.4,5.5};
        Arrays.stream(numbers).forEach(System.out::println);

     输出:

1.1
2.2
3.3
4.4
5.5

4.1.3 由值生成流

        IntStream number = IntStream.of(1,2,3,4);
        number.forEach(System.out::println);

        Stream<String> name = Stream.of("ZS","WHY","LMY","LF","SY","ZQM","HXL");
        name.forEach(System.out::println);

输出:

1
2
3
4
ZS
WHY
LMY
LF
SY
ZQM
HXL

4.1.4从文件中获取流

        Stream<String> context = null ;
        try {
            context = Files.lines(Paths.get("D:\\abc.txt"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        context.forEach(System.out::println);

输出

dsadsadsadasdasdsffghghjhhgfhdfsdsdsdgfg

4.1.5 从函数中生成流

    Stream中有两个静态方法生成流:Stream.iterate,Stream.generate,这两个方法可以生成无限流,所以一定要加limit限制大小

    Stream.iterate   

    输入:表示从1开始,x每次都加2

        Stream.iterate(1, x->x+2).
                limit(10).forEach(System.out::println);

输出:

1
3
5
7
9
11
13
15
17
19

再如:斐波那契数列,第三个数等于前两个数的和

        Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]})
                .limit(20)
                .map(t -> t[0])
                .forEach(System.out::println);
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181

Stream.generate

输入:

        IntSupplier fib = new IntSupplier() {
            private int previous = 0;
            private int current = 1;

            @Override
            public int getAsInt() {
                int oldPrevious = this.previous;
                int nextValue = this.previous + this.current;
                this.previous = this.current;
                this.current = nextValue;
                return oldPrevious;
            }
        };
        IntStream.generate(fib).limit(10).forEach(System.out::println);

输出:斐波那契数列

0
1
1
2
3
5
8
13
21
34

4.1.6 Map生成流

   输入

        Map<String, Object> map = new HashMap<>();
        map.put("name","WHY");
        map.put("AGE",26);
        map.put("SEX","MAN");
        Stream<Map.Entry<String, Object>> stream = map.entrySet().stream();
        stream.forEach(System.out::println);

 输出:

SEX=MAN
name=WHY
AGE=26

4.2 forEach遍历

        List<Integer> num = Arrays.asList(1,2,3,4,5,6);
        num.stream().forEach(System.out::println);

输出:

1
2
3
4
5
6

4.3 过滤

  4.3.1 filter 返回满足条件的数

        List<Integer> num = Arrays.asList(1,2,3,4,5,6);
        num.stream().filter(i -> i>2).filter(i ->i<5).forEach(System.out::println);

输出:

3
4

4.3.2 distinct 返回不重复的数据

        List<String> names = Arrays.asList("why","hehe","hehe","why","HAHA");
        names.stream().distinct().forEach(System.out::println);

输出:

why
hehe
HAHA

4.3.3 limit 限制返回元素个数

输入:

        List<String> names = Arrays.asList("why","hehe","hehe","why","HAHA");
        names.stream().distinct().limit(2).forEach(System.out::println);

输出:

why
hehe

4.3.4 skip 跳过前n个元素

输入:

        List<String> names = Arrays.asList("why","hehe","hehe","why","HAHA");
        names.stream().skip(2).forEach(System.out::println);

输出:

hehe
why
HAHA

4.4 Map映射

    4.4.1 map方法作用于每个元素,并且返回一个新的元素,map可以改变Stream的类型,例如下面例子把int变成了String

        List<Integer> list = Arrays.asList(1,2,3,4,5);
        list.stream().filter(i->i>=1).filter(j ->j<4).map(a->"第"+a+"个").forEach(System.out::println);

  输出:

第1个
第2个
第3个

   4.4.2 flatMap

     flatMap方法可以把各个数组映射的流合为一个流

        String str= "I love the world";
        Stream<String> strStream = Stream.of(str);
        strStream.flatMap(line->Arrays.stream(line.split(" "))).forEach(System.out::println);

输出:数组中每个元素的值

I
love
the
world

如果用map的话

        String str= "I love the world";
        Stream<String> strStream = Stream.of(str);
        strStream.map(line->Arrays.stream(line.split(" "))).forEach(System.out::println);

输出:一个流的数组

java.util.stream.ReferencePipeline$Head@1cf53f9

4.5 sorted 排序

输入:

                List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
                num.stream().sorted().forEach(System.out::println);

输出:

1
2
3
4
4
6
7

4.6 规约

4.6.1 reduce将流中的元素结合得到一个值

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        Integer sum = num.stream().reduce(Integer::sum).get();
        System.out.println(sum);
        Integer max = num.stream().reduce(Integer::max).get();
        System.out.println(max);
        Integer min = num.stream().reduce(Integer::min).get();
        System.out.println(min);

输出:

27
7
1

4.6.2 max和min,参数是Comparator

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        Integer max = num.stream().max(comparing(Integer::intValue)).get();
        System.out.println(max);
        Integer min = num.stream().min(comparing(Integer::intValue)).get();
        System.out.println(min);

输出:

7
1

4.6.3 Collectors 可将流转换成集合和聚合元素

输入:

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        List<Integer> newNum = num.stream().filter(i -> i>2).collect(Collectors.toList());
        System.out.println(newNum);

输出:

[4, 6, 7, 3, 4]

输入:合并字符串

        List<String> strings = Arrays.asList("I", "LOVE", "THE", "WORLD","hehe");
        String mergedString = strings.stream().filter(string -> !string.equals("hehe")).
                collect(Collectors.joining(" "));
        System.out.println(mergedString);

输出:

I LOVE THE WORLD

4.7 判断

4.7.1 anyMatch 表示是否存在满足要求的元素,有的话返回true

输入:

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        boolean result = num.stream().anyMatch(i->i==1);
        System.out.println(result);

返回:

true

4.7.2 allMatch 表示所有元素都满足条件才返回true

输入:

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        boolean result = num.stream().allMatch(i->i==1);
        System.out.println(result);

输出:

false

4.7.3  noneMatch 表示是否一个元素都不满足条件,与anyMatch相反

输入:

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        boolean result = num.stream().noneMatch(i->i==1);
        System.out.println(result);

输出:

false

4.7.4 findFirst 返回第一个元素

输入:

        List<Integer> num = Arrays.asList(4,2,6,1,7,3,4);
        Integer result = num.stream().findFirst().get();
        System.out.println(result);

输出:

4

4.8 数值流 

Stream<Integer>有装箱拆箱的操作,而IntStream,DoubleStream和LongStream分别表示流中的元素为int,double,long,可以避免装箱拆箱

4.8.1

输入:

public class Number {

    String name;
    int num;

    public Number(String name, int num) {
        this.name = name;
        this.num = num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}
        List<Number> list = Arrays.asList(new Number("why",60),new Number("hehe",70));
        IntStream intStream = list.stream().mapToInt(a -> a.getNum());
        int sum = intStream.sum();
        System.out.println(sum);
        IntStream intStream2 = list.stream().mapToInt(a -> a.getNum());
        int max = intStream2.max().getAsInt();
        System.out.println(max);
        IntStream intStream3 = list.stream().mapToInt(a -> a.getNum());
        int min = intStream3.min().getAsInt();
        System.out.println(min);
        IntStream intStream4 = list.stream().mapToInt(a -> a.getNum());
        double ave = intStream4.average().getAsDouble();
        System.out.println(ave);

输出:

130
70
60
65.0

4.8.2 range,rangeClosed

生成范围内的数,第一个参数接受起始值,第二个参数接受结束值,range不包含结束值,rangeClosed包含结束值

输入:

        IntStream.range(1, 100).filter(i->i>95).forEach(System.out::println);

输出:

96
97
98
99

猜你喜欢

转载自blog.csdn.net/xyy1028/article/details/83692901