Rewriting using streams in Java8

I need some help with how I would rewrite this code using streams in Java. I am new to coding and could use some assistance. Thank you for your time. I have this class called thisDoesStuff that uses the doControlMethod.

 public void thisDoesStuff() {
        MealType previousMealType = null;
        int count = 0;
        int total = 0;
        int min = 0;
        int max = 0;
        int median = 0;
        double mean = 0;
        int index;
        for (int i = 0; i < mealList.size(); i++) {
            if (mealList.get(i) != null) {
                previousMealType = mealList.get(i).getMealType();
                if (mealList.get(i).getMealType() != previousMealType && previousMealType != null) {
                    System.out.printf("%-9s %9s %9s %9s %9s %9s \n", previousMealType.getPrettyPrint(), total,
                            String.format("%" +
                                    ".2f",
                            mean), min, max, median);
                }
                min = mealList.get(i).getCalories();
                count++;
                total += mealList.get(i).getCalories();
                mean = (double) total / count;
                if (max < mealList.get(i).getCalories()) {
                    max = mealList.get(i).getCalories();
                }
                index = count / 2;
                median = mealList.get(index).getCalories();

            }
            System.out.printf("%-9s %9s %9s %9s %9s %9s \n", previousMealType.getPrettyPrint(), total, String.format(
                    "%.2f",
                    mean), min,
                    max, median);
        }


    }

2 answers

  • answered 2021-02-23 20:19 Susan Mustafa

    I am going to simply show you how to iterate without forloop. The logic you have inside your if statement is wrong.

       previousMealType = mealList.get(i).getMealType();
                    if (mealList.get(i).getMealType() != previousMealType && previousMealType != null) {
                        System.out.printf("%-9s %9s %9s %9s %9s %9s \n", previousMealType.getPrettyPrint(), total,
                                String.format("%" +
                                        ".2f",
                                mean), min, max, median);
                    }
    

    How is this working for you exactly? previousMealType will always be replaced to equal mealList.get(i).........

    I will just give you pointers...I will not rewrite it, as it feels like homework.

    MealType previousMealType = null;
    
    mealList.forEach(currentElement -> {
    
         
          //Logic goes here...
          if(currentElement != null){
    
                //Do something
             if(previousMealType != null && currentElement.getMealType() != previousMealType){
    
             }
             //Now set this, not first thing....
             previousMealType = currentElement.getMealType();
           }
     });
     
    

    or

     mealList.stream().forEach(currentElement -> {
         
          //Logic goes here...
          if(currentElement != null){
    
                //Do something
             if(previousMealType != null && currentElement.getMealType() != previousMealType){
    
             }
             //Now set this, not first thing....
             previousMealType = currentElement.getMealType();
           }
         
     });
    

    The elements in a list when using stream() are meant to be consumed one after the other, and not to do list.get(index);

  • answered 2021-02-24 14:37 daniu

    Well first of all, you seem to want to do this by meal type, so

    Map<MealType, List<Meal>> byType = meals.stream().groupingBy(mealList);
    

    For (most) of the things you're calculating, there's actually a class IntSummaryStatistics, so what you can do is

    for (List<Meal> fromSingleType : byType.getValueSet()) {
      IntSummaryStatistics stats = fromSingleType.stream()
        .mapToInt(Meal::getCalories)
        .collect(Collectors.summarizingInt());
      // stats has count, average, min, max. Missing the median though.
    }
    

    Median calculation is not done easily with streams, if at all, since you're always handling a single item at the time, so you don't known when you're "in the middle" of the value set. Best thing you can do is create a sorted list of all calory values and take caloryList.get(caloryList.size()/2).