Я пишу библиотеку для начинающих программистов, поэтому я стараюсь, чтобы API был как можно более чистым.
Одна из вещей, которую должна выполнить моя библиотека, - это выполнить некоторые сложные вычисления в большой коллекции ints или longs. Существует множество сценариев и бизнес-объектов, которые мои пользователи должны вычислить из этих значений, поэтому я подумал, что лучший способ - использовать потоки, чтобы позволить пользователям сопоставлять бизнес-объекты с IntStream
или LongStream
, а затем вычислять вычисления внутри коллектора.
Однако IntStream и LongStream имеют только метод сбора 3-х параметров:
collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)
И не имеет более простого метода collect(Collector)
, который Stream<T>
имеет.
Итак, вместо того, чтобы делать
Collection<T> businessObjs = ...
MyResult result = businessObjs.stream()
.mapToInt( ... )
.collect( new MyComplexComputation(...));
Я должен предоставить поставщиков, аккумуляторов и комбинаторов следующим образом:
MyResult result = businessObjs.stream()
.mapToInt( ... )
.collect(
()-> new MyComplexComputationBuilder(...),
(builder, v)-> builder.add(v),
(a,b)-> a.merge(b))
.build(); //prev collect returns Builder object
Это слишком сложно для моих начинающих пользователей и очень подвержено ошибкам.
Моя работа - сделать статические методы, которые принимают IntStream
или LongStream
как входные данные и скрывают создание и выполнение коллекционера для вас
public static MyResult compute(IntStream stream, ...){
return .collect(
()-> new MyComplexComputationBuilder(...),
(builder, v)-> builder.add(v),
(a,b)-> a.merge(b))
.build();
}
Но это не соответствует нормальным соглашениям о работе с Streams:
IntStream tmpStream = businessObjs.stream()
.mapToInt( ... );
MyResult result = MyUtil.compute(tmpStream, ...);
Потому что вам нужно либо сохранить временную переменную и передать ее статическому методу, либо создать поток внутри статического вызова, который может сбивать с толку, когда он смешивается с другими параметрами для моих вычислений.
Есть ли более чистый способ сделать это, продолжая работать с IntStream
или LongStream
?