Уменьшить операцию над пользовательским объектом в Java - PullRequest
0 голосов
/ 29 мая 2018

Как использовать операцию «Уменьшить» для выполнения суммы на двух полях объекта.

Например,

class Pojo
{
    public Pojo(int a, int b) {
        super();
        this.a = a;
        this.b = b;
    }
    int a ;
    int b;
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }

}

Pojo object1 = new Pojo(1, 1);
Pojo object2 = new Pojo(2, 2);
Pojo object3 = new Pojo(3, 3);
Pojo object4 = new Pojo(4, 4);

List<Pojo> pojoList = new ArrayList<>();

pojoList.add(object1);
pojoList.add(object2);
pojoList.add(object3);
pojoList.add(object4);

Я могу выполнить сумму, используя IntStream, например:

int sum = pojoList.stream()
                  .mapToInt(ob -> (ob.getA() + ob.getB()))
                  .sum();

Я хочу выполнить ту же самую операцию , используя Redu , но почему-то синтаксис неверен:

pojoList.stream()
        .reduce(0, (myObject1, myObject2) -> (myObject1.getA() + myObject2.getB()));

Ответы [ 5 ]

0 голосов
/ 29 мая 2018
class Pojo {
  static public Pojo add(Pojo p1, Pojo p2) {
    return new Pojo(p1.getA() + p2.getA(), p1.getB() + p2.getB())
  }
  //...
}

так далее:

Pojo pojoSum = pojoList.stream().reduce(new Pojo(0,0), Pojo::add);
pojoSum.getA() + pojoSum.getB()
0 голосов
/ 29 мая 2018

Используемая вами функция сокращения принимает BinaryOperator, который принимает два T-объекта в качестве аргументов, а возвращает T-объект .

.это функция уменьшения , которая работает с аккумулятором, вот как это использовать (см. ответ Эрана):

int sum = pojoList.stream()
                  .reduce(0 /* the identity for your binary operation, for sum this is 0 */, 
                         (s,ob)->s+ob.getA()+ob.getB() /* s is the accumulated value */,
                         Integer::sum /* combine accumulated values by sum */);
0 голосов
/ 29 мая 2018

То же, что и ответ Эрана:

int sum = pojoList.stream()
                  .mapToInt(ob ->(ob.getA()+ob.getB()))
                  .reduce(Integer::sum)
                  .orElse(0);

Просто для удовольствия вы можете сделать это также с помощью collect:

int result = pojoList.stream()
            .collect(
                    () -> new int[] { 0 },
                    (x, y) -> x[0] = x[0] + y.getA() + y.getB(),
                    (left, right) -> left[0] += right[0])[0];
0 голосов
/ 29 мая 2018

sum() реализация метода выглядит следующим образом:

public final int sum() {
    return reduce(0, Integer::sum);
}

Замена sum() на reduce():

int sum = pojoList.stream()
                  .mapToInt(ob -> (ob.getA() + ob.getB()))
                  .reduce(0, Integer::sum);

Или без mapToInt():

int pojoSum = pojoList.stream()
                      .reduce(0, (sum, ob) -> sum + ob.getA() + ob.getB(), Integer::sum);

Для получения дополнительной информации см. Операции сокращения , параграф.

0 голосов
/ 29 мая 2018

Что ж, если вы хотите позвонить на уменьшение на IntStream:

int sum = pojoList.stream()
                  .mapToInt(ob ->(ob.getA()+ob.getB()))
                  .reduce(0, (a,b)->a+b);

Конечно, то же самое будет работать на Stream<Integer>:

int sum = pojoList.stream()
                  .map(ob ->(ob.getA()+ob.getB()))
                  .reduce(0, (a,b)->a+b);

или сссылка на метод:

int sum = pojoList.stream()
                  .map(ob ->(ob.getA()+ob.getB()))
                  .reduce(0, Integer::sum);

или без map():

int sum = pojoList.stream()
                  .reduce(0, (s,ob)->s+ob.getA()+ob.getB(),Integer::sum);

В этом последнем примере я использую вариант:

<U> U reduce(U identity,
             BiFunction<U, ? super T, U> accumulator,
             BinaryOperator<U> combiner);

, так какприведенное значение (Integer) отличается от типа элементов Stream.

Первый параметр - это значение идентификатора - 0.

Второй параметр добавляет значения getA() и getB() текущего элемента Pojo к промежуточной сумме.

Третий параметр объединяет две частичные суммы.

...