Java JDK 1.8 新特性 Stream流

Stream流

stream流与IO流没有任何关系,stream流类似车间的生产线,对数据进行加工,不存储数据

获取Stream流的两种方式

public class StreamIntro {
    public static void main(String[] args) {
        // 方式一: 通过Collection接口的stream()方法获取流
        List<String> arrayList = new ArrayList<>();
        Stream<String> stream = arrayList.stream();

        Set<String> set = new HashSet<>();
        Stream<String> stream1 = set.stream();

        Map<String, String> map = new HashMap<>();
        Stream<String> stream2 = map.keySet().stream();
        Stream<String> stream3 = map.values().stream();
        Stream<Map.Entry<String, String>> stream4 = map.entrySet().stream();
        
        // 方式二: 通过Stream接口中的静态方法of获取流
        Stream<String> stream5 = Stream.of("zdy", "zyz", "cyx", "mcs");
        String[] strs = {"zdy", "zyz", "cyx", "mcs"};
        Stream<String> stream6 = Stream.of(strs);
    }
}

Stream常用方法

stream常用方法分为两类

终结方法:返回值不是Stream流类型的方法,不再支持链式调用,例如:count、forEach

非终结方法:返回值是Stream流类型的方法,支持链式调用,例如:filter、limit、map、skip

forEach方法

遍历集合中的每一个元素

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
        stream.forEach(System.out::println); // 打印 "zdy"  "zyz"  "cyx"  "mcs"
    }
}

count方法

计算集合的长度

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
        long count = stream.count();
        System.out.println(count); // 打印 4
    }
}

filter方法

自定义编写过滤规则,通过规则的数据留下,支持链式调用

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
        stream.filter(s -> s.contains("z")) // 包含"z"的留下
                .filter(s -> s.contains("y")) // 包含"y"的留下
                .forEach(System.out::println); // 打印 "zdy" "zyz"
    }
}

limit方法

取集合中的前n个数据

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
        stream.limit(2).forEach(System.out::println); // 打印 "zdy" "zyz"
    }
}

skip方法

从第几条数据开始取

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
        stream.skip(2).forEach(System.out::println); // 打印 "cyx" "mcs"
    }
}

map方法

将一种类型的流转换为另一种类型的流

public class StreamIntro {
    public static void main(String[] args) {
		// 通过map 将Stream类型转换为Stream类型
        Stream<String> stream = Stream.of("1", "2", "3", "4");
        Stream<Integer> stream1 = stream.map(Integer::parseInt);
    }
}

sorted方法

排序方法,支持自定义比较器

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(5, 2, 7, 4);
        stream.sorted((num1, num2) -> num1 - num2).forEach(System.out::println); // 打印 2 4 5 7
    }
}

distinct方法

去重方法

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("zdy", "zdy", "zyz", "zyz", "cyx", "mcs");
        stream.distinct().forEach(System.out::println); // 打印 "zdy" "zyz" "cyx" "mcs"
    }
}

match方法

匹配方法,细分为三个,allMatch所有数据都满足条件,anyMatch任意一条数据满足条件,noneMatch没有数据满足条件,都返回boolean类型

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(5, 2, 7, 4);
        boolean match = stream.allMatch(num -> num > 4); // 所有数据都>4吗
        System.out.println(match); // 打印 "false"

        Stream<Integer> stream2 = Stream.of(5, 2, 7, 4);
        boolean anyMatch = stream2.anyMatch(num -> num > 4); // 有数据>4吗
        System.out.println(anyMatch); // 打印 "true"

        Stream<Integer> stream3 = Stream.of(5, 2, 7, 4);
        boolean noneMatch = stream3.noneMatch(num -> num == 3); // 没有数据=3吗
        System.out.println(noneMatch); // 打印 "true"
    }
}

max方法

获取最大值,支持自定义比较器,通过比较器也可以实现min的功能

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(5, 2, 7, 4);
        Optional<Integer> max = stream.max((num1, num2) -> num1 - num2);
        System.out.println(max.get()); // 打印 "7"
    }
}

min方法

获取最小值,支持自定义比较器,通过比较器也可以实现max的功能

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(5, 2, 7, 4);
        Optional<Integer> min = stream.min((num1, num2) -> num1 - num2);
        System.out.println(min.get()); // 打印 "2"
    }
}

reduce方法

将所有的数据归纳为一个数据

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(5, 2, 7, 4);
        // 参数1 默认值 参数2 数据处理方式 以下代码可以理解为 reduce=默认值-5-2-7-4
        Integer reduce = stream.reduce(0, (num1, num2) -> num1 - num2);
        System.out.println(reduce); // -18
    }
}

concat方法

合并两个流

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
        Stream<Integer> stream2 = Stream.of(5, 2, 7, 4);
        Stream<? extends Serializable> stream = Stream.concat(stream1, stream2);
        stream.forEach(System.out::println); // 打印 "zdy" "zyz" "cyx" "mcs" 5 2 7 4
    }
}

收集Stream流中的结果

Stream流结果保存到集合中

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
        // 保存到Set中
        Set<String> collect = stream1.collect(Collectors.toSet());
        // 保存到List中
        List<String> collect1 = stream1.collect(Collectors.toList());
        // 保存到ArrayList
        ArrayList<String> collect2 = stream1.collect(Collectors.toCollection(ArrayList::new));
        // 保存到ArraySet
        HashSet<String> collect3 = stream1.collect(Collectors.toCollection(HashSet::new));
    }
}

Stream流结果保存到数组中

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
        // 保存成数组
        String[] strings = stream1.toArray(String[]::new);
    }
}

Collectors.maxBy/minBy/summarizingInt

对流中数据进行聚合计算

public class StreamIntro {
    public static void main(String[] args) {
        Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
        Stream<Person> stream = Stream.of(new Person("zdy", 23),
                new Person("zyz", 24),
                new Person("cyx", 25),
                new Person("mcs", 26));
        // maxBy 获取年龄最大值 minBy 获取最小值
        Optional<Person> collect = stream.collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println(collect.get());

        Stream<Person> stream2 = Stream.of(new Person("zdy", 23),
                new Person("zyz", 24),
                new Person("cyx", 25),
                new Person("mcs", 26));
        // summingInt 求年龄总和
        IntSummaryStatistics collect1 = stream2.collect(Collectors.summarizingInt(Person::getAge));
        // 年龄总和
        System.out.println(collect1.getSum());
        // 年龄平均值
        System.out.println(collect1.getAverage());
        // 统计数量
        System.out.println(collect1.getCount());
    }
}

Collectors.groupingBy

对流中数据进行分组 多级分组

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Person> stream2 = Stream.of(new Person("zdy", 23),
                new Person("zyz", 24),
                new Person("cyx", 23),
                new Person("mcs", 24));
        // 通过age进行分组 23一组 24一组
        Map<Integer, List<Person>> collect = stream2.collect(Collectors.groupingBy(Person::getAge));
        collect.forEach((k, v) -> {
            System.out.println(k + " " + v);
            // 打印 
            // 23 [Person(name=zdy, age=23), Person(name=cyx, age=23)]
			// 24 [Person(name=zyz, age=24), Person(name=mcs, age=24)]
        });
        
        Stream<Person> stream3 = Stream.of(new Person("zdy", 21),
                new Person("zyz", 22),
                new Person("cyx", 25),
                new Person("mcs", 24));
        // 年龄>23分一组 <23分一组
        Map<String, List<Person>> collect1 = stream3.collect(Collectors.groupingBy((person) -> {
            if (person.getAge() > 23) {
                return "高龄";
            } else {
                return "低龄";
            }
        }));
        collect1.forEach((k, v) -> {
            System.out.println(k + " " + v);
            // 打印 
            // 低龄 [Person(name=zdy, age=21), Person(name=zyz, age=22)]
			// 高龄 [Person(name=cyx, age=25), Person(name=mcs, age=24)]
        });
        
        Stream<Person> stream4 = Stream.of(new Person("zdy", 21),
                new Person("zyz", 22),
                new Person("cyx", 21),
                new Person("mcs", 22));
        // 多级分组 先根据年龄分组 再根据名字中是否含有"z"分组
        Map<Integer, Map<String, List<Person>>> collect2 = stream4.collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy((person) -> {
            if (person.getName().contains("z"))
                return "含有";
            else
                return "不含有";
        })));
        collect2.forEach((k, v) -> {
            System.out.println(k);
            v.forEach((key, value) -> {
                System.out.println("    " + key + " " + value);
                // 打印 
                // 21
				//     不含有 [Person(name=cyx, age=21)]
				//     含有 [Person(name=zdy, age=21)]
				// 22
				//     不含有 [Person(name=mcs, age=22)]
				//     含有 [Person(name=zyz, age=22)]
            });
        });
    }
}

Collectors.partitioningBy

对流中数据进行分区,true一区,false一区

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Person> stream2 = Stream.of(new Person("zdy", 21),
                new Person("zyz", 22),
                new Person("cyx", 25),
                new Person("mcs", 24));
        // 年龄>23分一区 <23分一区
        Map<Boolean, List<Person>> collect = stream2.collect(Collectors.partitioningBy(p -> {
            return p.getAge() > 23;
        }));
        collect.forEach((k, v) -> {
            System.out.println(k + " " + v);
            // 打印 
            // false [Person(name=zdy, age=21), Person(name=zyz, age=22)]
			// true [Person(name=cyx, age=25), Person(name=mcs, age=24)]
        });
    }
}

Collectors.joining

根据指定的字符串,将所有元素连接成一个字符串

public class StreamIntro {
    public static void main(String[] args) {
        Stream<Person> stream1 = Stream.of(new Person("zdy", 21),
                new Person("zyz", 22),
                new Person("cyx", 25),
                new Person("mcs", 24));
        // 根据一个字符进行拼接
        String collect = stream1.map(Person::getName).collect(Collectors.joining("_"));
        System.out.println(collect);
        // 打印 
        // zdy_zyz_cyx_mcs

        Stream<Person> stream2 = Stream.of(new Person("zdy", 21),
                new Person("zyz", 22),
                new Person("cyx", 25),
                new Person("mcs", 24));
        // 根据三个字符进行拼接 三个字符串分别为分隔符、前缀、后缀
        String collect1 = stream2.map(Person::getName).collect(Collectors.joining("_", "@", "^"));
        System.out.println(collect1);
        // 打印 
        // @zdy_zyz_cyx_mcs^
    }
}

并行Stream流

获取并行流的两种方式

public class StreamIntro {
    public static void main(String[] args) {
        // 方式一 直接获取并行流
        ArrayList<Object> list = new ArrayList<>();
        Stream<Object> stream = list.parallelStream();

        // 方式二 将串行流转换为并行流
        Stream<Integer> parallel = Stream.of(1, 3, 4, 5, 6, 7, 3, 2).parallel();

        long count = parallel.filter(num -> {
            System.out.println(Thread.currentThread() + " " + num);
            // 打印  由此可见是多个线程一起执行
            // Thread[main,5,main] 7
            // Thread[ForkJoinPool.commonPool-worker-23,5,main] 3
            // Thread[main,5,main] 6
            // Thread[ForkJoinPool.commonPool-worker-5,5,main] 2
            return num > 3;
        }).count();
    }
}

你可能感兴趣的:(java,java)