Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 Java Stream Api вернуть сумму и список за один проход. Оптимизация  [new]
serzuzekno
Member

Откуда:
Сообщений: 11
class Foo{
  int d;
  String n;
  int s;
  Foo(int d, String n, int s){
     this.d = d;
     this.n = n;
     this.s = s;
  }
}

List<Foo> foos = new ArrayList<>();
foos.add(new Foo(1, "a", 10));
foos.add(new Foo(1, "a", 15));
foos.add(new Foo(2, "b", 40));
foos.add(new Foo(3, "c", 60));
foos.add(new Foo(2, "b", 10));


Нужно получить List<Pair<Foo, Integer>>.
В value-Integer сумма всех s по d.

Возможно ли получить сумму s сгруппированную по d и одновременно вернуть сам список.

Если делать groupingBy(f->f.a) то получаем Integer a, List<Foo>

Как бы тут ещё получить сразу и сумму s. Ведь проход и так происходит при группировке по a.
10 сен 19, 09:30    [21967454]     Ответить | Цитировать Сообщить модератору
 Re: Java Stream Api вернуть сумму и список за один проход. Оптимизация  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2149
serzuzekno,
Чет я не понял. А где тут Stream?
10 сен 19, 09:34    [21967457]     Ответить | Цитировать Сообщить модератору
 Re: Java Stream Api вернуть сумму и список за один проход. Оптимизация  [new]
serzuzekno
Member

Откуда:
Сообщений: 11
PetroNotC Sharp, будет. Доберусь до работы)
10 сен 19, 09:49    [21967472]     Ответить | Цитировать Сообщить модератору
 Re: Java Stream Api вернуть сумму и список за один проход. Оптимизация  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 2149
serzuzekno,
Аааа, дак это не вопрос, а описание как ты проводишь день))))). Понял.
10 сен 19, 09:58    [21967479]     Ответить | Цитировать Сообщить модератору
 Re: Java Stream Api вернуть сумму и список за один проход. Оптимизация  [new]
забыл ник
Member

Откуда:
Сообщений: 3024
reduce()
10 сен 19, 10:57    [21967514]     Ответить | Цитировать Сообщить модератору
 Re: Java Stream Api вернуть сумму и список за один проход. Оптимизация  [new]
serzuzekno
Member

Откуда:
Сообщений: 11
существующее решение:

import javafx.util.Pair;
import java.util.*;
import java.util.stream.Collectors;

class Foo{
    int d;
    String n;
    int s;
    Foo(int d, String n, int s){this.d = d; this.n = n; this.s = s; }
    public String toString() {return "d " + d + ",n " + n + ",s " + s;}
}
public class Main {

    public static void main(String[] args) {
        List<Foo> foos = new ArrayList<>();
        foos.add(new Foo(1, "a", 10));
        foos.add(new Foo(1, "a", 15));
        foos.add(new Foo(2, "b", 40));
        foos.add(new Foo(3, "c", 60));
        foos.add(new Foo(2, "b", 10));      
    }


}


трубуется результат

25=d 1,n a,s 10
25=d 1,n a,s 15
50=d 2,n b,s 40
50=d 2,n b,s 10
60=d 3,n c,s 60


вариант1
  
foos.stream()
                .collect(Collectors.groupingBy(foo -> foo.d))
                .values()
                .stream()
                .map(l -> new Pair<>(l.stream().mapToInt(f -> f.s).sum(), l))
                .flatMap(p -> p.getValue().stream().map( f-> new Pair<>(p.getKey(),f) ))
                .forEach(System.out::println);


вариант2, выглядит оптимальнее, но громоздко. Тут делим список по ключу и сразу суммируем
        
foos.stream()
                .collect(Collectors.toMap(f -> f.d
                                    , f -> new Pair<>(f.s, new ArrayList<>(Collections.singletonList(f)))
                                    , (p, p2) -> {
                                            p.getValue().addAll(p2.getValue());
                                            return new Pair<>(p.getKey() + p2.getKey(), p.getValue());
                                        }
                        )
                ).values()
                .stream()
                .flatMap(p -> p.getValue().stream().map( f-> new Pair<>(p.getKey(),f) ))
                .forEach(System.out::println);



суть вопроса - можно ли как то написать красивый стрим как в 1ом варианте, но оптимизированный как во втором
10 сен 19, 11:03    [21967519]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить