DIY一个Java8的Collector:MyListCollector

目标

完成一个简单的MyListCollector,能将对应的Stream转换为List

Collector是什么?

举个具体的例子:

list.stream().filter(x -> x > 2).collect(new MyListCollector());

我们想要将一个list中大于2的所有元素都筛选出来,首先list转化为stream,对每一个元素进行判断。但是判断完以后,我们如何将stream转换为我们想要的类型呢?这时候可以使用collect()方法,collect()方法需要的参数就是一个Collector,这个Collector告诉了collect方法,如何去将这个stream转换为我们想要的对象。

Collector接口

collect方法接收的Collector,都必须实现Collector接口,我们简单的看一下Collector接口:

  1. 先来看一下泛型
  • TCollector需要操作的对象,也就是传进来的参数;
  • A:中间容器,操作过程中存储T的容器;
  • R:返回的结果。
  1. 看一下接口方法
public interface Collector<T, A, R> {

    Supplier<A> supplier();

    BiConsumer<A, T> accumulator();

    BinaryOperator<A> combiner();
    
    Function<A, R> finisher();
    
    Set<Characteristics> characteristics();
}

Collector接口需要我们实现的一共五个,前4个定义了如何将传进来的数据进行处理返回。最后一个方法定义了是否允许使用多线程处理,如何优化处理过程。

  • Supplier<A> supplier():提供一个容器,即接口泛型的A,所以返回类型Supplier<A>的泛型(返回类型)为A。所以我们的接口此方法实现为:
	public Supplier<List<E>> supplier() {
        return ArrayList::new;
    }
  • BiConsumer<A, T> accumulator():这个方法定义了如何处理传入的参数。T为传入的参数,A为容器,也就是说,如何将传入的参数(A)放到容器(T)里。我们的接口,此方法实现为:
public BiConsumer<List<E>, E> accumulator {
	return List::add;
}
  • Function<A, R> finisher():我们刚刚已经提到了,A只是作为一个中间容器,R才是最终的返回值。这个方法,就是用于定义如何将容器转换为最终结果的。所以我们的接口此方法的实现为:
public Function<List<E>, List<E>> finisher() {
	return Function.identity();
}
  • BinaryOperator<A> combiner():此方法用于,当Stream被分割为多个的时候,如何将多个中间容器结合在一起。
public BinaryOperator<A> combiner() {
	return (l1, l2) -> {
		l1.addAll(l2);
		return l1;
	}
}
  • Set<Characteristics> characteristics():这个方法返回一个Set<Characteristics>Characteristics是一个枚举类,一共有三个取值:
    UNORDERED:返回的结果是无序的;
    CONCURRENT:该Collector可以在多线程环境下使用,如果此Collector不是UNORDERED,那么这个Collector只有传入的数据是无序的时候,才能在多线程环境下使用;
    IDENTITY_FINISH:中间容器和返回值的类型一致。A转换为R的时候,不需要检查。
MyListCollector

结合以上,我们的接口实现为:

public class MyListCollector<E> implements Collector<E, List<E>, List<E>>{
    @Override
    public Supplier<List<E>> supplier() {
        return ArrayList::new;
    }

    @Override
    public BiConsumer<List<E>, E> accumulator() {
        return List::add;
    }

    @Override
    public BinaryOperator<List<E>> combiner() {
        return (list1, list2) -> {
            list1.addAll(list2);
            return list1;
        };
    }

    @Override
    public Function<List<E>, List<E>> finisher() {
        return Function.identity();
    }

    @Override
    public Set<Characteristics> characteristics() {
        return null;
    }
}

参考:Java 8 in action

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值