lambda(四)

方法引用

ClassName:methodName   凡是使用lambda表达式的地方就可以使用方法引用。

artist->artist.getName();
Artist::getName

上下等价

(id,name) -> new Artist(id,name);
Artist::new

元素顺序

如果进来的流是无序的,出去的流也是无序的。比如set

foreach方法不能保证元素是按照顺序处理的foreachOrdered方法可以。

收集器

转换成其他集合

.stream().collect(TreeSet::new);
new ArrayList<String>().stream().collect(toMap(p->p,p->p));

转换成值

取最大值

Function<String,Integer> getLength = s -> s.length();
    Optional<String> count = stringList.collect(maxBy(Comparator.comparing(getLength)))

取平均值

collect(averagingInt(list->list.size()))

数据分块

收集器 partitioningBy , 它接受一个流,并将其分成两部分,它使用Predicate 对象判断一个元素应该属于哪个部分,并根据返回值,进行分类得到Map<Boolean,List<T>>

数据分组

groupingBy 收集器,接受一个分类函数,接受一个Function 对象。

Map<Person,List<Album>>albums.collect(groupingBy(Album::getPersion))

字符串

artists.stream()
        .map(Artist::getName)
        .collect(Collectors.joining(",","[","]"));

使用map操作提取出艺术家的姓名,然后使用Collectors.joining收集流中的值,该方法可以方便的从一个流得到一个字符串,参数分别为 分隔符,前缀,后缀  输出[a,b,c,d]

组合收集器

下游收集器,用以收集最终结果的一个子集,生成器是生成最终结果的一剂配方,下游收集器则是生成部分结果的配方,主收集器会用到下游收集器。

public Map<Artist,Long> numberOfAlbums(Stream<Album> albums){
    return albums.collect(groupingBy(album ->album.getMainMusician
            ,counting()));
}

mapping 收集器,允许在收集器的容器上执行类似map的操作。但是需要指明使用什么样的集合类存储结果,比如toList()

public Map<Artist,List<String> numberOfAlbums(Stream<Album> albums){
    return albums.collect(groupingBy(Album::getMainMusician
            ,mapping(Album::getName,toList())));
}

 

定制收集器

首先实现collector接口,

T  待收集元素的类型

A 累加器的类型

R 最终结果的类型

一个收集器由四部分组成,

supplier 工厂方法,用来创建容器;

accumulator 作用和reduce操作的第二个参数一样,它结合之前操作的结果和当前值,生成并返回新的值。accumulator 用于将流中的值叠加入容器中,

combiner 像reduce操作的第三个方法,如果有两个容器,我们需要将其合并。

finisher 我们已经将流中的值叠加入一个可变容器中,但这还不是我们想要的最终结果。这里调用了finisher方法,以便进行转换。

特征。特征是一组描述收集器的对象,框架可以对其适当优化

 

public interface Collector<T, A, R> {
    /**
     * A function that creates and returns a new mutable result container.
     *
     * @return a function which returns a new, mutable result container
     */
    Supplier<A> supplier();

    /**
     * A function that folds a value into a mutable result container.
     *
     * @return a function which folds a value into a mutable result container
     */
    BiConsumer<A, T> accumulator();

    /**
     * A function that accepts two partial results and merges them.  The
     * combiner function may fold state from one argument into the other and
     * return that, or may return a new result container.
     *
     * @return a function which combines two partial results into a combined
     * result
     */
    BinaryOperator<A> combiner();

    /**
     * Perform the final transformation from the intermediate accumulation type
     * {@code A} to the final result type {@code R}.
     *
     * <p>If the characteristic {@code IDENTITY_TRANSFORM} is
     * set, this function may be presumed to be an identity transform with an
     * unchecked cast from {@code A} to {@code R}.
     *
     * @return a function which transforms the intermediate result to the final
     * result
     */
    Function<A, R> finisher();

    /**
     * Returns a {@code Set} of {@code Collector.Characteristics} indicating
     * the characteristics of this Collector.  This set should be immutable.
     *
     * @return an immutable set of collector characteristics
     */
    Set<Characteristics> characteristics();

    /**
     * Returns a new {@code Collector} described by the given {@code supplier},
     * {@code accumulator}, and {@code combiner} functions.  The resulting
     * {@code Collector} has the {@code Collector.Characteristics.IDENTITY_FINISH}
     * characteristic.
     *
     * @param supplier The supplier function for the new collector
     * @param accumulator The accumulator function for the new collector
     * @param combiner The combiner function for the new collector
     * @param characteristics The collector characteristics for the new
     *                        collector
     * @param <T> The type of input elements for the new collector
     * @param <R> The type of intermediate accumulation result, and final result,
     *           for the new collector
     * @throws NullPointerException if any argument is null
     * @return the new {@code Collector}
     */
    public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
                                              BiConsumer<R, T> accumulator,
                                              BinaryOperator<R> combiner,
                                              Characteristics... characteristics) {
        Objects.requireNonNull(supplier);
        Objects.requireNonNull(accumulator);
        Objects.requireNonNull(combiner);
        Objects.requireNonNull(characteristics);
        Set<Characteristics> cs = (characteristics.length == 0)
                                  ? Collectors.CH_ID
                                  : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,
                                                                           characteristics));
        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs);
    }

    /**
     * Returns a new {@code Collector} described by the given {@code supplier},
     * {@code accumulator}, {@code combiner}, and {@code finisher} functions.
     *
     * @param supplier The supplier function for the new collector
     * @param accumulator The accumulator function for the new collector
     * @param combiner The combiner function for the new collector
     * @param finisher The finisher function for the new collector
     * @param characteristics The collector characteristics for the new
     *                        collector
     * @param <T> The type of input elements for the new collector
     * @param <A> The intermediate accumulation type of the new collector
     * @param <R> The final result type of the new collector
     * @throws NullPointerException if any argument is null
     * @return the new {@code Collector}
     */
    public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
                                                 BiConsumer<A, T> accumulator,
                                                 BinaryOperator<A> combiner,
                                                 Function<A, R> finisher,
                                                 Characteristics... characteristics) {
        Objects.requireNonNull(supplier);
        Objects.requireNonNull(accumulator);
        Objects.requireNonNull(combiner);
        Objects.requireNonNull(finisher);
        Objects.requireNonNull(characteristics);
        Set<Characteristics> cs = Collectors.CH_NOID;
        if (characteristics.length > 0) {
            cs = EnumSet.noneOf(Characteristics.class);
            Collections.addAll(cs, characteristics);
            cs = Collections.unmodifiableSet(cs);
        }
        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
    }

    /**
     * Characteristics indicating properties of a {@code Collector}, which can
     * be used to optimize reduction implementations.
     */
    enum Characteristics {
        /**
         * Indicates that this collector is <em>concurrent</em>, meaning that
         * the result container can support the accumulator function being
         * called concurrently with the same result container from multiple
         * threads.
         *
         * <p>If a {@code CONCURRENT} collector is not also {@code UNORDERED},
         * then it should only be evaluated concurrently if applied to an
         * unordered data source.
         */
        CONCURRENT,

        /**
         * Indicates that the collection operation does not commit to preserving
         * the encounter order of input elements.  (This might be true if the
         * result container has no intrinsic order, such as a {@link Set}.)
         */
        UNORDERED,

        /**
         * Indicates that the finisher function is the identity function and
         * can be elided.  If set, it must be the case that an unchecked cast
         * from A to R will succeed.
         */
        IDENTITY_FINISH
    }
}

computeIfAbsent

public Aritst getArtist(String name){
    // 如果name 为空则调用 name->this.readArtistFormDB(DB);
    return artistCache.computeIfAbsent(name,this::readArtistFromDB);
}

遍历map

java 8 为map 接口 新增了一个forEach方法,方法接受一个BiConsumer 对象(该对象接受两个参数,返回为空)

for(Map.Entry<Artist,List<Album>> entry: albumsByArtist.entrySet()){
    map.put(entry.getKey(),entry.getValue().size());
}
albumsByArtist.forEach((artist,albums)->{
    map.put(artist,albums.size())
})

转载于:https://my.oschina.net/haloooooo/blog/1829199

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值