好的,我查看了Collectors 的实现,您需要CollectorImpl 来创建自定义收集器,但它不公开。所以我使用它的副本来实现一个新的(你可能感兴趣的最后两种方法):
public class CollectorUtils<T, A, R> implements Collector<T, A, R> {
static final Set<Collector.Characteristics> CH_ID = Collections
.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
private final Supplier<A> supplier;
private final BiConsumer<A, T> accumulator;
private final BinaryOperator<A> combiner;
private final Function<A, R> finisher;
private final Set<Characteristics> characteristics;
CollectorUtils(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
Function<A, R> finisher, Set<Characteristics> characteristics) {
this.supplier = supplier;
this.accumulator = accumulator;
this.combiner = combiner;
this.finisher = finisher;
this.characteristics = characteristics;
}
CollectorUtils(Supplier<A> supplier, BiConsumer<A, T> accumulator, BinaryOperator<A> combiner,
Set<Characteristics> characteristics) {
this(supplier, accumulator, combiner, castingIdentity(), characteristics);
}
@Override
public BiConsumer<A, T> accumulator() {
return accumulator;
}
@Override
public Supplier<A> supplier() {
return supplier;
}
@Override
public BinaryOperator<A> combiner() {
return combiner;
}
@Override
public Function<A, R> finisher() {
return finisher;
}
@Override
public Set<Characteristics> characteristics() {
return characteristics;
}
@SuppressWarnings("unchecked")
private static <I, R> Function<I, R> castingIdentity() {
return i -> (R) i;
}
public static <C extends Collection<File>> Collector<String, ?, C> toFile() {
return new CollectorUtils<>((Supplier<List<File>>) ArrayList::new, (c, t) -> {
c.add(toFile(t));
}, (r1, r2) -> {
r1.addAll(r2);
return r1;
}, CH_ID);
}
private static File toFile(String fileName) {
try (Closeable type = () -> System.out.println("Complete! closing file " + fileName);) {
// stuff
System.out.println("Converting " + fileName);
return new File(fileName);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
throw new RuntimeException("Failed to create file");
}
}
然后我如下调用流:
public static void main(String[] args) {
Stream.of("x.txt", "y.txt","z.txt").collect(CollectorUtils.toFile());
}
输出:
Convertingx.txt
closing filex.txt
Convertingy.txt
closing filey.txt
Convertingz.txt
closing filez.txt