java8 Stream类

来源:互联网 发布:小米推送php demo 编辑:程序博客网 时间:2024/06/05 16:47

java8的Stream用于串联组合函数,直到调用了一个聚合函数(count、max、min等)才会产生一个输出。Stream的中间操作返回的还是Stream,Stream不是立即求值,而是暂存了一系列的操作,直到调用了终结函数才会求值。

创建Stream

String[] strings = "Mary had a little lamb".split(" ");// 接受一个数组Stream<String> stream = Stream.of(strings);// 接受可变长度的参数Stream<String> stream2 = Stream.of("Mary", "had", "a", "little", "lamb");// 创建不含任何元素的StreamStream<String> stream3 = Stream.empty();// 创建无限长度的StreamStream<String> stream4 = Stream.generate(() -> "Mary");

流转换

filter

Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// filter方法用于对数组进行过滤,filter方法的入参为Predicate对象。// filter为数组上的所有元素执行函数,将返回true的元素创建一个新的Stream返回。Stream.of(arr).filter(x -> x % 2 == 0).forEach(System.out::println); // 返回偶数 [2,4,6,8,10]

concat

Integer[] arr1 = { 1, 2, 3, 4, 5 };Integer[] arr2 = { 6, 7, 8, 9, 10 };// concat用于合并两个流Stream.concat(Stream.of(arr1), Stream.of(arr2))    .forEach(System.out::println); // [1,2,3,4,5,6,7,8,9,10]

map和flatMap

Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// map对流中每个元素执行函数,并返回一个新的值Stream.of(arr).map(x -> x * 10).forEach(System.out::println); // 每个数乘以10 [10,20,30,40,50,60,70,80,90,100]String[] arr2 = { "Hello", "World" };// flatMap用于流的扁平化,flatMap将流中的元素转换成另一个流(map的作用),然后再将这些流合并(concat的作用)Stream.of(arr2).map(x -> x.split("")) // [[H, e, l, l, o], [W, o, r, l, d]]    .flatMap(Arrays::stream) // [H, e, l, l, o, W, o, r, l, d]    .forEach(System.out::println);

limit和skip

Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// limit返回包含n个元素的新流Stream.of(arr).limit(5).forEach(System.out::println); // [1,2,3,4,5]// skip跳过n个元素Stream.of(arr).skip(5).forEach(System.out::println); // [6,7,8,9,10] // limit为5,一旦找到第5个元素,就不会再调用filter方法了Stream.of(arr).filter(x -> {    System.out.println("x = " + x); // 只会打印5次    return x < 6;}).limit(5).collect(Collectors.toList()); // [1,2,3,4,5]

流的聚合

reduce

Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// reduce方法用于对所有元素与累加器做运算Optional<Integer> optional = Stream.of(arr).reduce((x, y) -> x + y); // sum,无初始值返回的是Optional对象Integer sum = Stream.of(arr).reduce(0, (x, y) -> x + y); // 有初始值

max和min

Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };Optional<Integer> max = Stream.of(arr).max(Integer::compare);Optional<Integer> min = Stream.of(arr).min(Integer::compare);

收集器

collect方法

聚合操作将流聚合为一个值,如果要查看或处理流中的数据,则需要使用收集器。
collect方法接受三个参数:
1、创建目标类型实例的方法,如ArrayList::new
2、将元素添加到目标中的方法,如ArrayList::add
3、将两个对象整合到一起的方法,如ArrayList::addAll

public class Test {    public static Stream<Person> people() {        return Stream.of(new Person(1001, "Peter"), new Person(1002, "Paul"), new Person(1003, "Mary"), new Person(1003, "Mary2"));    }    public static void main(String[] args) throws IOException {        List<Person> list = people().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);        System.out.println(list);    }}class Person {    private int id;    private String name;    public Person(int id, String name) {        this.id = id;        this.name = name;    }    public int getId() {        return id;    }    public String getName() {        return name;    }    public String toString() {        return getClass().getName() + "[id=" + id + ",name=" + name + "]";    }}

Collectors提供了一些常见的工厂方法用于数据收集,如toList、toMap等。

joining、maxBy、toList

String[] strings = "Mary had a little lamb".split(" ");// Mary,had,a,little,lambString str = Stream.of(strings).collect(Collectors.joining(","));Integer[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };Optional<Integer> max = Stream.of(arr).collect(Collectors.maxBy(Integer::compare)); // 10// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]List<Integer> list = Stream.of(arr).collect(Collectors.toList());

toMap

public class Test {    public static Stream<Person> people() {        return Stream.of(new Person(1001, "Peter"), new Person(1002, "Paul"), new Person(1003, "Mary"));    }    public static Stream<Person> people2() {        return Stream.of(new Person(1001, "Peter"), new Person(1002, "Paul"), new Person(1003, "Mary"), new Person(1003, "Mary2"), new Person(1003, "Mary2"));    }    public static void main(String[] args) throws IOException {        // toMap用于将结果收集到一个map中,toMap第一个参数是返回key,第二个参数是value,        // 使用Function.identity()返回实际的元素(等同于x->x)        // {1001=Person(1001, "Peter"), 1002=Person(1002, "Paul"), 1003=Person(1003, "Mary")}        people().collect(Collectors.toMap(Person::getId, Function.identity()));        people().collect(Collectors.toMap(Person::getId, x -> x));        // 如果多个元素有相同的key,会抛出IllegalStateException异常,需要使用第三个参数自行处理        // {1001=Person(1001, "Peter"), 1002=Person(1002, "Paul"), 1003=Person(1003, "Mary2")}        people2().collect(Collectors.toMap(Person::getId, Function.identity(),                 (existingValue, newValue) -> newValue)); // 返回新元素        // {1001=[Person(1001, "Peter")], 1002=[Person(1002, "Paul")], 1003=[Person(1003, "Mary"), Person(1003, "Mary2")]}        people2().collect(Collectors.toMap(Person::getId, Collections::singleton,             (existingValue, newValue) -> {                Set<Person> set = new HashSet<>();                set.addAll(existingValue);                set.addAll(newValue);                return set;            }        ));    }}class Person {    private int id;    private String name;    public Person(int id, String name) {        this.id = id;        this.name = name;    }    public int getId() {        return id;    }    public String getName() {        return name;    }    public String toString() {        return getClass().getName() + "[id=" + id + ",name=" + name + "]";    }}

summerizing

summerizing可以用于统计多个数据:总和、平均值、最大值、最小值、总数

String[] strings = "Mary had a little lamb".split(" ");IntSummaryStatistics summary = Stream.of(strings).collect(Collectors.summarizingInt(String::length));double avg = summary.getAverage(); // 3.6int max = summary.getMax(); // 6

groupingBy

public class Test {    public static Stream<Person> people() {        return Stream.of(new Person(1001, "Peter"), new Person(1002, "Paul"), new Person(1003, "Mary"), new Person(1003, "Mary2"));    }    public static void main(String[] args) throws IOException {        // {1001=[Person(1001, "Peter")], 1002=[Person(1002, "Paul")], 1003=[Person(1003, "Mary"), Person(1003, "Mary2")]}        // map的值是List        Map<Integer, List<Person>> map = people().collect(Collectors.groupingBy(x -> x.getId()));        // map的值是Set        Map<Integer, Set<Person>> map2 = people().collect(Collectors.groupingBy(x -> x.getId(), Collectors.toSet()));        // 对分组后的元素count        // {1001=1, 1002=1, 1003=2}        Map<Integer, Long> map3 = people().collect(Collectors.groupingBy(x -> x.getId(), Collectors.counting()));        // 对分组后的元素自定义操作        // {1001=[Peter], 1002=[Paul], 1003=[Mary2, Mary]}        Map<Integer, Set<String>> map4 = people().collect(                Collectors.groupingBy(x -> x.getId(), Collectors.mapping(Person::getName, Collectors.toSet())));    }}class Person {    private int id;    private String name;    public Person(int id, String name) {        this.id = id;        this.name = name;    }    public int getId() {        return id;    }    public String getName() {        return name;    }    public String toString() {        return getClass().getName() + "[id=" + id + ",name=" + name + "]";    }}
0 0