Я пытаюсь создать реализацию Java 8 Collector для ImmutableList от Guava. Но я продолжаю получать странные ошибки нулевого указателя. Что не так с моим коллекционером?My ImmutableList Collector не работает?
java.lang.NullPointerException на java.util.stream.ReferencePipeline.collect (Unknown Source) в com.swa.rm.common.test.TestLauncher.main (TestLauncher.java:50)
это ошибка я получаю, когда я пытаюсь запустить этот код ...
ImmutableList.of (1,5,2,7,8,2,4) .stream(). фильтр (i -> i% 2 == 0) .collect (новый ImmutableListCollector()) .forEach (i -> System.out.println (i));
, который вызывает этот коллектор
package com.swa.rm.common.stream;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import com.google.common.collect.ImmutableList;
public class ImmutableListCollector<T> implements Collector<T, ImmutableList.Builder<T>, ImmutableList<T>> {
@Override
public Supplier<ImmutableList.Builder<T>> supplier() {
return ImmutableList::builder;
}
@Override
public BiConsumer<ImmutableList.Builder<T>, T> accumulator() {
return (builder, t) -> builder.add(t);
}
@Override
public BinaryOperator<ImmutableList.Builder<T>> combiner() {
return (left, right) -> {
left.addAll(right.build());
return left;
};
}
@Override
public Function<ImmutableList.Builder<T>, ImmutableList<T>> finisher() {
return null;
}
@Override
public Set<Characteristics> characteristics() {
return EnumSet.of(Characteristics.UNORDERED);
}
}
UPDATE :: Вот окончательная реализация, и, кажется, работает в настоящее время.
import java.util.EnumSet;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import com.google.common.collect.ImmutableList;
public class ImmutableListCollector<T> implements Collector<T, ImmutableList.Builder<T>, ImmutableList<T>> {
@Override
public Supplier<ImmutableList.Builder<T>> supplier() {
return (() -> ImmutableList.builder());
}
@Override
public BiConsumer<ImmutableList.Builder<T>, T> accumulator() {
return (builder, t) -> builder.add(t);
}
@Override
public BinaryOperator<ImmutableList.Builder<T>> combiner() {
return (left, right) -> {
left.addAll(right.build());
return left;
};
}
@Override
public Function<ImmutableList.Builder<T>, ImmutableList<T>> finisher() {
return (b -> builder.build());
}
@Override
public Set<Characteristics> characteristics() {
return EnumSet.of(Characteristics.UNORDERED);
}
}
FYI, ваша окончательная реализация выглядит некорректной, так как ее 'поставщик()' возвращает тот же экземпляр 'ImmutableList.Builder', а не создает новый каждый раз. Это связано с несколькими проблемами, включая: A) компоновщик может быть добавлен из нескольких потоков одновременно, когда он не является потокобезопасным; B) 'combiner()' будет добавлять все элементы строителя к самому строителю; C) сам «Коллекционер» является состоятельным и не может быть повторно использован. – ColinD
Да, я действительно понял это, и я переключил поставщика, чтобы каждый раз приносить новый экземпляр строителя, и избавляю вас от того, что он висит сверху как свойство. Я обновлю код выше, чтобы отразить это позже сегодня. – tmn