Stream(流)是一个支持顺序和平行聚合操作的元素序列,和java.util.List类似,是jdk1.8的新特性。可以看出Stream还有几个兄弟类IntStream、LongStream和DoubleStream。

/**
 * @param <T> the type of the stream elements
 * @since 1.8
 * @see IntStream
 * @see LongStream
 * @see DoubleStream
 * @see <a href="package-summary.html">java.util.stream</a>
 */
public interface Stream<T> extends BaseStream<T, Stream<T>> {
    ......
}

本章主要以集合流来介绍Stream的详细使用

目录

一、实例方法

操作类方法

转换类方法

遍历类方法

获取类方法

判断类方法

二、静态方法


一、实例方法

操作类方法

1、Stream<T> filter(Predicate<? super T> predicate);

过滤掉流中不符合断言规则的元素,得到一个新的Stream对象

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();
        Stream<String> stringStream = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.contains("o");
            }
        });

        System.out.println(
                Arrays.toString(
                        stringStream.toArray()
                )
        );
    }

}

以上代码的作用是输出集合list中包含字符串"o"的元素。

运行结果:

[Hello, Tom, Jhon, Jackson, Jackson, Jackson]

2、Stream<T> distinct();

去重

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        System.out.println(
                Arrays.toString(
                        stream.distinct().toArray()
                )
        );
    }

}

去重后,只有一个Jackson

[Hello, Tom, Marry, Jhon, Lisa, Jim, Jackson]

3、Stream<T> sorted();

对流的元素排序,如果是字母,按照字母的顺序从a~z、A~Z排序

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        System.out.println(
                Arrays.toString(
                        stream.sorted().toArray()
                )
        );
    }

}

排序后,打印结果为

[Hello, Jackson, Jackson, Jackson, Jhon, Jim, Lisa, Marry, Tom]

4、Stream<T> sorted(Comparator<? super T> comparator);

排序,并自定义排序规则,Comparator应该都不陌生——比较器接口,在集合的排序方法Collections.sort()中就用到了

如:按照字符串长度排序

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        System.out.println(
                Arrays.toString(
                        stream.sorted(new Comparator<String>() {
                            @Override
                            public int compare(String o1, String o2) {
                                return o1.length() - o2.length();
                            }
                        }).toArray()
                )
        );
    }

}

长度相同的按照原有的先后顺序排序,运行结果如下

[Tom, Jim, Jhon, Lisa, Hello, Marry, Jackson, Jackson, Jackson]

5、Stream<T> peek(Consumer<? super T> action);

元素遍历,这里有涉及到了Consumer函数这个接口,和Function接口的功能几乎一样

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        stream.peek(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s.toLowerCase());
            }
        }).toArray();
    }

}

以上代码把元素全部转为小写字母然后打印

hello
tom
marry
jhon
lisa
jim
jackson
jackson
jackson

6、Stream<T> limit(long maxSize);

修改Stream中元素的个数

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        System.out.println(
                Arrays.toString(
                        stream.limit(5).toArray()
                )
        );
    }

}

最后只保留了前5个元素,运行结果如下

[Hello, Tom, Marry, Jhon, Lisa]

7、Stream<T> skip(long n);

跳过前n个元素,也就是删除前n个元素

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        System.out.println(
                Arrays.toString(
                        stream.skip(5).toArray()
                )
        );
    }

}

跳过了前五个元素,就只剩下最后四个元素

[Jim, Jackson, Jackson, Jackson]

转换类方法

1、<R> Stream<R> map(Function<? super T, ? extends R> mapper);

用于转化流的类型,得到的Stream对象类型为R,也就是Function的返回值类型

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();
        Stream<Boolean> booleanStream = stream.map(new Function<String, Boolean>() {
            @Override
            public Boolean apply(String s) {
                return s.equals("Hello");
            }
        });

        System.out.println(
                Arrays.toString(
                        booleanStream.toArray()
                )
        );
    }

}

显然,只有第一个元素为true,其他都是false

[true, false, false, false, false, false, false, false, false]

2、IntStream mapToInt(ToIntFunction<? super T> mapper);

转为IntStream 对象

3、LongStream mapToLong(ToLongFunction<? super T> mapper);

转为LongStream 对象

4、DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);

转为DoubleStream 对象

5、<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

批量操作流中的所有元素,得到一个新的流对象

6、IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);

作用同mapToInt()

7、LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);

作用同mapToLong()

8、DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);

作用同mapToDouble()

9、Object[] toArray();

使用当前Stream对象的所有元素生成一个数组,整篇文章基本都在使用这个方法,就不过多介绍了。

10、<A> A[] toArray(IntFunction<A[]> generator);

作用和上一个方法一样,参数类型A要求是当前Stream对象的泛型的超类,否则会抛出
ArrayStoreException异常,下面的代码将得到包含Stream对象里所以元素的数组并遍历打印

import java.util.ArrayList;
import java.util.List;
import java.util.function.IntFunction;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        String[] array = stream.toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[list.size()];
            }
        });

        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }

}

11、Optional<T> reduce(BinaryOperator<T> accumulator);

对当前Stream对象的所有元素执行一定操作,得到一个Optional对象,操作的结果就是Optional对象的value值。

例如,把Stream对象的元素拼接起来得到一个Optinal对象

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        Optional<String> optional = stream.reduce(new BinaryOperator<String>() {
            @Override
            public String apply(String s, String s2) {
                return s.concat(s2);
            }
        });

        System.out.println(optional.get());
    }

}

运行结果

HelloTomMarryJhonLisaJimJacksonJacksonJackson


12、T reduce(T identity, BinaryOperator<T> accumulator);

该方法作用和上一个方法一样,但是可以指定返回值类型,返回值类型就是第一个参数的类型

import java.util.ArrayList;
import java.util.List;
import java.util.function.BinaryOperator;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();
        String result = stream.reduce("", new BinaryOperator<String>() {
            @Override
            public String apply(String s, String s2) {
                return s.concat(s2);
            }
        });

        System.out.println(result);
    }

}

运行结果和上一个方法一样,都是把Stream对象的所有元素拼接起来

HelloTomMarryJhonLisaJimJacksonJacksonJackson

13、<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

14、<R, A> R collect(Collector<? super T, A, R> collector);

15、<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);

遍历类方法

1、void forEach(Consumer<? super T> action);

很明显,这个方法就是用来遍历当前Stream对象里的元素

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
    }

}

直接打印所有的元素

Hello Tom Marry Jhon Lisa Jim Jackson Jackson Jackson

2、void forEachOrdered(Consumer<? super T> action);

按正序遍历元素,同forEach()

package test;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("Hello");
        list.add("Tom");
        list.add("Marry");
        list.add("Jhon");
        list.add("Lisa");
        list.add("Jim");
        list.add("Jackson");
        list.add("Jackson");
        list.add("Jackson");

        Stream<String> stream = list.stream();

        stream.forEachOrdered(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
    }

}

运行结果和上一个方法一样

获取类方法

1、Optional<T> min(Comparator<? super T> comparator);

获取当前Stream对象中元素的最小值

2、Optional<T> max(Comparator<? super T> comparator);

获取当前Stream对象中元素的最大值

3、long count();

获取当前Stream对象中元素的个数,用法很简单,就不贴代码了

4、Optional<T> findFirst();

得到一个包含当前Stream对象的第一个元素的Optinal对象

5、Optional<T> findAny();

得到一个包含当前Stream对象的任意一个元素的Optinal对象

判断类方法

1、boolean anyMatch(Predicate<? super T> predicate);

判断当前Stream对象的元素中有没有元素符合断言,如果有,则返回true,否则返回false

2、boolean allMatch(Predicate<? super T> predicate);

判断当前Stream对象的元素是否全部符合断言,如果是,返回true,否则返回false

3、boolean noneMatch(Predicate<? super T> predicate);

该方法和anyMatch()相反,没有元素符合断言返回true,否则返回false

二、静态方法

1、static<T> Stream<T> empty()

返回一个空的顺序流

2、static<T> Stream<T> of(T t)

指定元素创建一个顺序流

3、static<T> Stream<T> of(T... values)

通过指定的多个元素创建一个顺序流