• Java8新特性----Stream


    Stream

    Stream 是用函数式编程方式在集合类上进行复杂操作的工具。 

    一)常用的流操作

    惰性求值方法:只描述Stream,最终不产生新集合的方法(返回的还是Stream)。

    及早求值方法:最终会从Stream产生值的方法。

    1.创建Stream:

    java.util.Collection<E> 

    default Stream<E> stream()

    default Stream<E> paralleStream()

    产生当前集合中所有元素的流,paralleStream()以并行的方式产生。

    java.util.stream.Stream 

    static <T> Steam<T> of(T...values)

    产生一个元素为给定值的流

    static <T> Stream<T> empty()

    产生一个不包含任何元素的流

    static <T> Stream<T> generate(Supplier<T> s)

    产生一个无限流,它的值是通过反复调用函数s而构建的

    static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)

    产生一个无限流,它的元素包含种子、在种子上调用f产生的值,在前一个元素上调用f产生的值

    java.util.Arrays 

    static <T> Stream<T> stream(T[] array, int off, int len)

    产生一个流,它的元素是由数组中指定范围内的元素构成。

    java.util.regex.Pattern 

    Stream<String> splitAsStream(CharSequence input)

    产生一个流,它的元素是输入中该模式界定的部分。

    java.nio.file.Files     

    static Stream<String> lines(Path path)

    static Stream<String> lines(Path path, Charset cs)

    获取值产生一个流,它的元素是指定文件中的行,该文件的字符集为UTF-8,或者为指定的字符集。

    java.util.function.Supplier<T> T get()

     2 //该方法接受可变长度的参数
     3 Stream<String> s=Stream.of("tang","jia","jiu");
     7 
     8 Stream.generate(Supplier<T> s);
     9 Stream<String> echos=Stream.generate(() -> "Echo");
    Stream<Double> random = Stream.generate(Math::random);
    Stream<String> pattern = Pattern.compile("\|").splitAsStream(str);
    10 //如果要创建一个行如0 1 2 3.......的无限序列可使用: 
    12 Stream<BigInteger> integers=Stream.iterate(BigInteger.ZERO,n -> n.add(BigInteger.ONE));

    2.转换Steam

    java.util.stream.Stream

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

    转换一个流中的值,并产生一个新的流。

    1 List<String> collected = Stream.of("a", "b", "hello")
    2 .map(string -> string.toUpperCase()) //Lambda 表达式必须是 Function 接口的一实例
    3 .collect(toList());
    4 assertEquals(asList("A", "B", "HELLO"), collected);

     Stream<T> filter(Predicate<? super T> predicate)

    产生一个新的流,包含符合某种条件的所有元素。

    1 List<String> beginningWithNumbers
    2 = Stream.of("a", "1abc", "abc1")
    3 .filter(value -> isDigit(value.charAt(0))) //必须是Predicate
    4 .collect(toList());

    <R> Stream<R> flatMap(Function<? super T, ? extends Steam<? extends R>> mapper)

    flatMap 方法可用 Stream 替换值, 然后将多个 Stream 连接成一个 Stream 

    1 List<Integer> together = Stream.of(asList(1, 2), asList(3, 4))
    2 .flatMap(numbers -> numbers.stream()) //必须是Function
    3 .collect(toList());
    4 assertEquals(asList(1, 2, 3, 4), together);

    Stream<T> limit(long n)

    返回一个包含前n个元素的新流。

    Stream<T> skip(int n)

    与之相反会丢弃掉前面的n个元素,返回新流。

    static <T> Stream<T> contact(Stream<? extends T> a, Stream<? extends T> b)

    拼接a和b两个流

    Stream<T> distinct()

    产生一个抑制了相同元素的新流。

    Stream<T> sorted()

    Stream<T> sorted(Comparator<? super T> comparator)

    产生一个流,它的元素是当前流中所有元素按顺序排列的,第一个方法要求元素是

    实现了Comparable的类的实例。

    Stream<T> peek(Consumer<? super T> action)

    产生一个流,它的元素与流中的元素相同,但在每次获取一个元素时,都会调用一个函数,这对调试来说非常方便。

    3.得到值

    java.util.stream.Stream 

    Optional<T> max(Comparator<? super T> compartor)

    Optional<T> min(Comparator<? super T> compartor)

    分别得到这个流的最大元素和最小元素

    Optional<T> findFirst()

    Optional<T> findAny()

    分别得到这个流的第一个和任意一个元素

    boolean anyMatch(Predicate<? super T> predicate)

    boolean allMatch(Predicate<? super T> predicate)

    boolean noneMatch(Predicate<? super T> predicate)

    分别在这个流中任意元素、所有元素和没有元素匹配给定断言时返回true。

    这些操作都是终结操作。

    4.Optional类型

    Optional<T>是一种包装器对象,要么包装了类型T的对象,要么没有包装任何对象。

    有效使用Optional的关键:它在值不存在的情况下会产生一个可替代物,而只有在值

    存在的情况下才会使用这个值。

    在没有任何匹配时,使用默认值:

    String result = optionalStr.orElse("");
    String result = optionalStr.orElseGet(() -> Locale.getDefault().getDisplayName());
    String result = optionalStr.orElseThrow(IllegalStateException::new)

    值存在是使用值:

    optionalValue.ifPresent(v -> Process V);
    optionalValue.ifPresent(v -> result.add(v));
    //注意调用ifPresent不会返回任何值,如果想要结果可使用map
    optionValue.map(results::add);

    java.util.Optional 

    T orElse(T other)

    获取Optional的值,或者在Optional为空时,产生other

    T orElseGet(Supplier<? extends T> other)

    获取Optional的值,或者在Optional为空时,获取调用other产生的结果

    <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

    获取Optional的值,或者在Optional为空时,抛出异常。

    void ifPresent(Consumer<? super T> consumer)

    如果该Optional不为空,那么就将它的值传递给consumer

    <U> Optional<U> map(Function<? super T, ? extneds U> mapper)

    获取将该Optional值传递给mapper后的结果,只要这个Optional的结果不为

    空且结果不为null,否则产生一个空Optional。

    不适合使用Optional值的方式: 

    Optional<T> optionalValue = ...;
    optionalValue.get().someMethod();
    //并不比下面的方式安全:
    T value = ...;
    value.someMethod();
    if (optionalValue.isPresent()) optionalValue.get().someMethod()
    //并不比下面的方式简单:
    if (value != null) value.someMethod();

    java.util.Optional 

    T get()

    获取Optional的值,或者在该Optional为空时,抛出NoSuchElementException。

    boolean isPresent()

    如果Optional不为空时,返回true。

    static <T> Optional<T> of(T value)

    static <T> Optional<T> ofNullable(T value)

    产生一个具有给定值的Optional。如果value为null,那么第一个方法会抛出

    NullPointerException对象,而第二个方法会产生一个空Optional.

    static <T> Optional<T> empty()

    产生一个空Optional。

    <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)

    产生将mapper应用于当前Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional

    5.收集器

    java.util.stream.BaseStream 

    Iterator<T> iterator()

    产生一个用于获取当前流中各个元素的迭代器。

    java.util.stream.Stream 

    void forEach(Consumer<? super T> action)

    在流的每个元素上调用action,这是一个终结操作,会以任意顺序遍历各个元素。

    Object[] toArray()

    <A> A[] toArray(IntFunction<A[]> generator)

    产生一个数组对象,或者在将引用A[]::new传递给构造器时,返回一个A类型的数组。

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

    使用给定的收集器来收集当前流中的元素,Collectors类中有多种收集器的工厂方法。

    java.util.stream.Collectors 

    static <T> Collector<T,?,List<T>> toList()

    static <T> Collector<T,?,Set<T>> toSet()

    产生一个收集器

    static <T,C extends Collection<T>> Collector<T,?,C> toCollection(Supplier<C> collectionFactory)

    产生一个将元素收集到任意集合中的收集器。可以传递一个诸如TreeSet::new的构造器引用。

    static Collector<CharSequence,?,String> joining()

    static Collector<CharSequence,?,String> joining(CharSequence delimiter)

    static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

    产生一个链接字符串的收集器,分隔符会置于字符串之间,而第一个字符串可之前可以有前缀,最后一个字符串之后可以有后缀。

    static <T> Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFuntion<? super T> mapper)

    static <T> Collector<T,?,LongSummaryStatistics> summarizingLong(ToLongFuntion<? super T> mapper)

    static <T> Collector<T,?,DoubleSummaryStatistics> summarizingDouble(ToDoubleFuntion<? super T> mapper)

    产生对应的SummaryStatistics收集器,通过它可以进行各自计算

    IntSummaryStatistics

    LongSummaryStatistics

    DoubleSummaryStatistics 

    long getCount()

    (int|long|double) getSum()

    double getAverage()

    (int|long|double) getMax()

    (int|long|double) getMin()

    收集到map中:

    Map<Integer, String> idToName = users.stream().collect(Collectors.toMap
                    (User::getUserId, User::getName));
    Map<Integer, User> userMap = users.stream().collect(Collectors
                    .toMap(User::getUserId, Function.identity()));

    java.util.stream.Collector

    static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T, ? extends K> key, Function<? super T, ? extends U> value) 

    key:产生Map的键  value:产生Map的值

    static <T,K,U> Collector<T,?,Map<K,U>> toMap(Function<? super T, ? extends K> key,

    Function<? super T, ? extends U> value,BinaryOperator<U> mergeFunction)

    如果多个元素具有相同的键就会存在冲突,收集器会抛异常。mergeFunction函数引元来覆盖这种行为,

    该函数会针对给定的已有值和新值来解决冲突并确定键对应的值。这个函数该返回已有值,新值或者它们的组合。

    static <T,K,U,M> Collector<T,?,M> toMap(Function<? super T, ? extends K> key,

    Function<? super T, ? extends U> value,BinaryOperator<U> mergeFunction,Supplier<M> mapSupplier)

    mapSupplier:例如TreeMap::new

    群组和分区:

    java.util.stream.Collectors 

    static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)

    返回一个收集器,它会产生一个映射表,其键是将classifier应用于所有收集到的元素上产生的结果,

    而值是由具有相同键的元素构成的一个个列表。

    static <T, K> Collector<T, ?, Map<Boolean, List<T>> partitioningBy(Predicate<? super T> predicate)

    产生一个收集器,它会产生一个映射表,其键是ture或者false,而值是由满足或者不满足断言的元素构成的列表。

    6.下游收集器 

    groupingBy()方法会产生一个Map,它的每个值都是一个List。如果想要以某种方式来处理这些List,

    就需要提供一个下游收集器。例如,如果想要获得Set而不是列表,那么可以使用Collector.toSet:

    java.util.stream.Collectors 

    static <T> Collector<T,?,Long> counting()

    产生一个可以对收集到的元素进行计数的收集器。

    static <T> Collector<T,?,Integer> summingInt(ToIntFunction<? super T> mapper)

    求和

    此外还有maxBy,minBy,mapping

    7.聚合操作

    一般来说,如果聚合方法有一个聚合操作op,那么该操作会产生v0 op v1 op v2......,其中 vop vi+1就表示我们编写的函数调用op(vi,vi+1).

    该操作应该是联合的,即与你组合元素的顺序无关。

    1 Stream<Integer> values=.....;
    2 Optional<Integer> sum=values.reduce((x,y) -> x+y);

    通常,如果有一个标识e使得e op x=x,那么你就可以使用该元素作为计算的起点。

    Optional<Integer> sum=values.reduce(0,(x,y) -> x+y);

    当流为空时会返回标识值。

    假设现在你有包含多个对象的流,并且希望对它的某个属性求和。

    int result=words.reduce(0,
         (total,word) -> total+word.length(),  
         (total1,total2) -> total1+total2);      
  • 相关阅读:
    vue--todolist的实现
    vue--使用定时器的问题
    vue--动态路由和get传值
    vue--非父子组件之间的传值
    Atitit 图像处理之仿油画效果 Oilpaint油画滤镜 水彩画 漫画滤镜 v2
    Atitit 图像处理 公共模块 矩阵扫描器
    Atitit 文档资料管理同步解决方案
    Atitit 拦截数据库异常的处理最佳实践
    Atitit 数据处理查询 中的异常标准化草案 jpa jdbc hb  oql规范attilax总结
    Atitit oodbms的查询,面向对象的sql查询jpa jpql hql
  • 原文地址:https://www.cnblogs.com/Shadowplay/p/10302491.html
Copyright © 2020-2023  润新知