Java >> Java tutorial >  >> Tag >> return

Hvordan man opsummerer de enkelte felter i objektlisten og returnerer resultaterne som et enkelt objekt

Du kan bruge Stream.reduce metode til det, skal du bare oprette en NutrientsAggregator som vil vide at tilføje værdierne fra FoodNutritional til sig selv og summere alt

public class NutrientsAggregator {
   private double calories;
   private double totalFat;
   private double saturatedFat;
   private double cholesterol;

   public NutrientsAggregator addFoodNutritionalValues(FoodNutritional foodNutrional) {
      this.calories += foodNutrional.getCalories();
      this.totalFat+= foodNutrional.getTotalFat();
      this.saturatedFat+= foodNutrional.getSaturatedFat();
      this.cholesterol+= foodNutrional.getCholesterol();

      return this;
   }
}

og end:

NutrientsAggregator result = response.getBody()
          .stream()
          .reduce(new NutrientsAggregator(), 
                  (aggregator, food) -> aggregator.addFoodNutritionalValues(food);

Lad introducere klasse NutritionAccumulator :

class NutritionAccumulator{
    private double fat = 0.;
    private double carbs = 0.;
    private double fiber = 0.;
    private double protein = 0.;

    public NutritionAccumulator() {
    }

    public NutritionAccumulator(double fat, double carbs, double fiber, double protein) {
        this.fat = fat;
        this.carbs = carbs;
        this.fiber = fiber;
        this.protein = protein;
    }

    public NutritionAccumulator add(NutritionAccumulator that){
        return new NutritionAccumulator(this.fat + that.fat,
        this.carbs + that.carbs,
        this.fiber + that.fiber,
        this.protein + that.protein
        );
    }
}

Og nu kan vi skrive simpel strømreduktion:

Optional.ofNullable(response.body())
.stream()
.reduce(
                        new NutritionAccumulator(),
                        (acc, fudNut) -> new NutritionAccumulator(
                                fudNut.getTotalFat(),
                                fudNut.getTotalCarbohydrate(),
                                fudNut.getDietaryFiber(),
                                fudNut.getProtein()
                        ).add(acc),
                        NutritionAccumulator::add

                );

Og endelig kan du videregive resultatet fra oven til bygherren.


Hvad med at bruge en Supplier<Stream<T>>> for at oprette en genbrugelig Stream noget som :

Supplier<Stream<FoodNutritional>> foodNutritionalSupplier = () -> Optional.ofNullable(responseBody)
        .stream()
        .flatMap(List::stream);
return Nutrients.builder()
        .carbohydrates(foodNutritionalSupplier.get().mapToDouble(FoodNutritional::getTotalCarbohydrate).sum())
        .protein(foodNutritionalSupplier.get().mapToDouble(FoodNutritional::getProtein).sum())
        .fat(foodNutritionalSupplier.get().mapToDouble(FoodNutritional::getTotalFat).sum())
        .dietaryFiber(foodNutritionalSupplier.get().mapToDouble(FoodNutritional::getDietaryFiber).sum())
        .build();

hvor responseBody svarer til response.getBody() i spørgsmålet.

Eller videre til at bruge et hjælpeprogram til at abstrahere kernelogikken, såsom:

private Nutrients nutrientsCalculator(List<FoodNutritional> responseBody) {
    Supplier<Stream<FoodNutritional>> foodNutritionalSupplier =
            () -> Optional.ofNullable(responseBody).stream().flatMap(List::stream);
    // should ideally be as simple as 'responseBody::stream'
    return Nutrients.builder()
            .carbohydrates(sumNutrition(foodNutritionalSupplier, FoodNutritional::getTotalCarbohydrate))
            .protein(sumNutrition(foodNutritionalSupplier, FoodNutritional::getProtein))
            .fat(sumNutrition(foodNutritionalSupplier, FoodNutritional::getTotalFat))
            .dietaryFiber(sumNutrition(foodNutritionalSupplier, FoodNutritional::getDietaryFiber))
            .build();
}

private Double sumNutrition(Supplier<Stream<FoodNutritional>> foodNutritionalSupplier,
                            ToDoubleFunction<FoodNutritional> nutritionTypeFunction) {
    return foodNutritionalSupplier.get().mapToDouble(nutritionTypeFunction).sum();
}

Java tag