Designing object oriented clean code structure with spring services I'm writing spring app for storing and manipulating recipes. I wrote ShoppingList service which generates, based on UUIDs of recipes, shopping list. This is my current model for which i wrote tests and works as intended.
Service uses another service called IngredientConverter which converts to response models. Now i wanted to move some dependency to ShoppingList as this function is jealous of functions, but approached a problem. How can a this class use IngredientConverter service without ugly passing it to ShoppingList function? Are there any tips you could give my code and structure planning?
@Service
@AllArgsConstructor
public class ShoppingListService {

    private final RecipeService recipeService;
    private final IngredientConverter ingredientConverter;

    public ShoppingList generateShoppingList(List&lt;UUID&gt; uuidsOfRecipes) {
        List&lt;Recipe&gt; recipes = recipeService.getAllByIDIn(uuidsOfRecipes);
        ShoppingList shoppingList = ShoppingList.empty();

        Map&lt;Ingredient, Integer&gt; ingredients = new HashMap&lt;&gt;();

        recipes.forEach(recipe -&gt;
                recipe.getIngredients().forEach(
                        ingredientQuantity -&gt;
                                ingredients.compute(
                                        ingredientQuantity.getIngredient(),
                                        (key, value) -&gt;
                                                value == null ?
                                                        ingredientQuantity.getAmount() :
                                                        value + ingredientQuantity.getAmount())));

        ingredients.keySet().forEach(
                ingredient -&gt;
                        shoppingList.getIngredients().add(
                                ingredientConverter.convertWithAmount(
                                        ingredient.getName(),
                                        ingredients.get(ingredient),
                                        ingredient.getUnit())
                        )

        );

        return shoppingList;
    }

}

@Data
@AllArgsConstructor
public class ShoppingList {

    private final List&lt;IngredientQuantity&gt; ingredients;

    public static ShoppingList of(List&lt;IngredientQuantity&gt; ingredients) {
        return new ShoppingList(ingredients);
    }

    public static ShoppingList empty(){
        return ShoppingList.of(new ArrayList&lt;&gt;());
    }

}


@Service
public class IngredientConverter {

 public IngredientQuantity convertWithAmount(String name, int amount, Unit unit) {
        return IngredientQuantity.builder()
                .amount(amount)
                .ingredient(convert(name, unit))
                .build();
    }
}


@Data
@Entity
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class IngredientQuantity extends IdentifiableEntity {

    private int amount;
    @ManyToOne
    private Ingredient ingredient;
}

@Data
@Getter
@Entity
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class Ingredient extends IdentifiableEntity {

    private String name;
    @Enumerated(EnumType.STRING)
    private Unit unit;
}

@Getter
@NoArgsConstructor
@SuperBuilder
@MappedSuperclass
public class IdentifiableEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID ID;
}
```
I would inject the converterservice into ShoppingList and implement an add() function, which adds an element to the ShoppingList after conversion.
void add(name, ingredient, unit) {
    IngredientQuantity toAdd = this.converterService.convert(name, ingredient, unit); // terrible naming, todo!
    this.ingredients.add(toAdd);
}

Now the shopping list is the owner of conversion which (arguably) is modelling real life. When I need to shop for milk, I convert the American recipes to litres instead of ounces or whatever.
This also simplifies your last lambda function, you just need to iterate over the keyset and call ShoppingList::add, which is Java8+ method ref syntax.
The other huge lambda should probably also be split into parts, I mean, I love functional java as much as anyone, but I believe this is cutting the line of functional utility over readability.
Pseudocode
foreach Recipe:
    foreach Ingredient : Recipe
        compute(ingredient)

These are my 2 cents.