select t3.name, sum(t3.prod_A) as Prod_A, sum(t3.prod_B) as Prod_B, sum(t3.prod_C) as Prod_C, sum(t3.prod_D) as Prod_D, sum(t3.prod_E) as Prod_E
from
(select t2.name as name,
case when t2.prodid = 1 then t2.counts
else 0 end prod_A,
case when t2.prodid = 2 then t2.counts
else 0 end prod_B,
case when t2.prodid = 3 then t2.counts
else 0 end prod_C,
case when t2.prodid = 4 then t2.counts
else 0 end prod_D,
case when t2.prodid = "5" then t2.counts
else 0 end prod_E
from
(SELECT partners.name as name, sales.products_id as prodid, count(products.name) as counts
FROM test.sales left outer join test.partners on sales.partners_id = partners.id
left outer join test.products on sales.products_id = products.id
where sales.partners_id = partners.id and sales.products_id = products.id group by partners.name, prodid) t2) t3
group by t3.name ;
Ответ гораздо лучше, чем использование spliteratorUnknownSize
напрямую, что также легче и дает лучший результат. Iterable
имеет метод spliterator()
, поэтому вы должны просто использовать его для получения вашего разделителя. В худшем случае тот же код (реализация по умолчанию использует spliteratorUnknownSize
), но в более общем случае, когда ваш Iterable
уже является коллекцией, вы получите лучший разделитель и, следовательно, лучшую производительность потока ( возможно, даже хороший параллелизм.) Его также меньше кода:
StreamSupport.stream(iterable.spliterator(), false)
.filter(...)
.moreStreamOps(...);
Как вы можете видеть, получение потока из Iterable (см. Почему Iterable & lt; T & gt; не предоставляет поток () и parallelStream ()? ) не очень болезненна.
Так как еще один ответ упоминал, что Guava поддерживает это, используя:
Streams.stream(iterable);
Я хочу подчеркнуть, что реализация делает что-то немного отличное от других предложенных ответов. Если Iterable
имеет тип Collection
, они бросают его.
public static <T> Stream<T> stream(Iterable<T> iterable) {
return (iterable instanceof Collection)
? ((Collection<T>) iterable).stream()
: StreamSupport.stream(iterable.spliterator(), false);
}
public static <T> Stream<T> stream(Iterator<T> iterator) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(iterator, 0),
false
);
}
Я создал этот класс:
public class Streams {
/**
* Converts Iterable to stream
*/
public static <T> Stream<T> streamOf(final Iterable<T> iterable) {
return toStream(iterable, false);
}
/**
* Converts Iterable to parallel stream
*/
public static <T> Stream<T> parallelStreamOf(final Iterable<T> iterable) {
return toStream(iterable, true);
}
private static <T> Stream<T> toStream(final Iterable<T> iterable, final boolean isParallel) {
return StreamSupport.stream(iterable.spliterator(), isParallel);
}
}
Я думаю, что он отлично читается, потому что вам не нужно думать о spliterators и booleans (isParallel).
Если вы используете Vavr (ранее известный как Javaslang), это может быть так же просто, как:
Iterable i = //...
Stream.ofAll(i);
Если вы можете использовать библиотеку Guava, начиная с версии 21, вы можете использовать
Streams.stream(iterable)
Lists.newArrayList(Iterable)
.
– Jacob van Lingen
3 February 2017 в 15:06
Очень простая работа для этой проблемы заключается в создании интерфейса Streamable<T>
, расширяющего Iterable<T>
, который содержит метод default <T> stream()
.
interface Streamable<T> extends Iterable<T> {
default Stream<T> stream() {
return StreamSupport.stream(spliterator(), false);
}
}
Теперь любой из ваших Iterable<T>
s могут быть тривиально сделаны потоковыми, просто объявив их implements Streamable<T>
вместо Iterable<T>
.
Я хотел бы предложить использовать библиотеку JOOL , она скрывает магию spliterator за вызовом Seq.seq (iterable), а также предоставляет целую кучу дополнительных полезных функций.
Вы можете легко создать Stream
из Iterable
или Iterator
:
public static <T> Stream<T> stream(Iterable<T> iterable) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
iterable.iterator(),
Spliterator.ORDERED
),
false
);
}
stream(...)
загромождает ваш код?
– gexicide
29 May 2014 в 12:42
Stream
был бы приятным, например.Stream.ofIterable(iterable)
. – robinst 27 August 2015 в 05:35