0

Hello I'm trying to sort a list in the following order

Breakfast -> Lunch -> Dinner -> Dessert->Breakfast -> Lunch -> Dinner -> Dessert 

getAllMealPlans([Cake (dessert), Vegetable Soup (lunch), Waffles (breakfast), Potato Gratin (dinner)], 4)

returns a set containing four plans:

 * - [ Waffles (breakfast), Vegetable Soup (lunch), Potato Gratin (dinner), Cake (dessert)] * - [Vegetable Soup (lunch), Potato Gratin (dinner), Cake (dessert), Waffles (breakfast)] * - [Potato Gratin (dinner), Cake (dessert), Waffles (breakfast), Vegetable Soup (lunch)] * - [Cake (dessert), Waffles (breakfast), Vegetable Soup (lunch), Potato Gratin (dinner)] 

This is what the enum and the Food type looks like

public enum Meal { BREAKFAST, LUNCH, DINNER, DESSERT } public static class Food { String dish; public Meal meal; public Food(String dish, Meal meal) { this.dish = dish; this.meal = meal; } 

This is what I have I can't quite get the sorting to work. Any ideas on how I can approach this?

public static Set<List<Food>> getAllMealPlans(Set<Food> foods, int numMeals) { Set<List<Food>> set = new HashSet<>(); List<Food> aList = new ArrayList<Food>(foods); List<String> sortedList = aList.stream().map(Meal::valueOf).sorted(Meal::compareTo).map(Meal::toString).collect(Collectors.toList()); System.out.println(sortedList); return set; } 
2
  • What you want is rather different from traditional "sorting". It seems like you want to group Foods into groups of 4, each group contains at most one breakfast, one lunch, one dinner, and one dessert, and joins all the groups together to form a list? Commented Nov 8, 2020 at 9:44
  • Breakfast > Lunch > Dinner > Dessert > Breakfast can never be sorted. What do you mean by "sort"? Commented Nov 8, 2020 at 9:46

3 Answers 3

1

I think what you want to do is sort the list "aList" by the meal ...

This should work

aList.stream().sorted((a,b) -> a.meal.compareTo(b.meal)).collect(Collectors.toList()); 

You can concatenate multiple lists by using "flatMap" like this

List<Food> listOfFoods = mealPlans.stream().flatMap(List<Food>::stream).collect(Collectors.toList()); System.out.println(Arrays.toString(listOfFoods.toArray())); 
Sign up to request clarification or add additional context in comments.

Comments

0

You want to implement Comparable in the Food class (or write a Comparator, like in Javaman's reply). See e.g. https://howtodoinjava.com/java/collections/java-comparable-interface/.

I'd also write a toString method for Food so that you don't have to map to String to display it in a pretty way.

However, maybe you are using the wrong datatype? Wouldn't you want a Map here so you can e.g. look up what's for breakfast? The key would be the enum and the value the Food. SortedMap should give you the items in the correct order.

What is the actual problem? Your description and code don't really match. Do you want all possible plans, i.e. combinations of dish and meal, or just one sorted plan?

Comments

0

The presented code snippet has several issues:

  1. numMeals parameter is not used anywhere in getAllMealPlans
  2. Empty result set is always returned -- it's not populated
  3. Compilation error: aList is a list of Food and it is not ever mapped to Meal to apply Meal's method references
  4. Redundant wrapping of List<Food> aList = new ArrayList<Food>(foods);

As the expected output is to provide a set containing lists of food shifted by one, this could be implemented as shown below along with the fixes of the mentioned issues:

public static Set<List<Food>> getAllMealPlans(Set<Food> foods, int numMeals) { Set<List<Food>> set = new LinkedHashSet<>(); // LinkedHashSet to keep insertion order // sort food by meal List<Food> sortedList = foods.stream() .sorted(Comparator.comparing(Food::getMeal)) // or Comparator.comparing(food -> food.meal) .collect(Collectors.toList()); // populate the result set starting from sorted list for (int i = 0; i < numMeals; i++) { set.add(sortedList); // rotated shift left by 1 Food first = sortedList.get(0); sortedList = new ArrayList<>(sortedList.subList(1, sortedList.size())); sortedList.add(first); } return set; } 

Method Food::toString needs to be overridden like this:

static class Food { //... @Override public String toString() { return String.format("%s (%s)", dish, meal.name().toLowerCase()); } } 

Test

getAllMealPlans(Set.of( new Food("Cake", Meal.DESSERT), new Food("Vegetable Soup", Meal.LUNCH), new Food("Waffles", Meal.BREAKFAST), new Food("Potato Gratin", Meal.DINNER) ), 4).forEach(System.out::println); 

Output:

[Waffles (breakfast), Vegetable Soup (lunch), Potato Gratin (dinner), Cake (dessert)] [Vegetable Soup (lunch), Potato Gratin (dinner), Cake (dessert), Waffles (breakfast)] [Potato Gratin (dinner), Cake (dessert), Waffles (breakfast), Vegetable Soup (lunch)] [Cake (dessert), Waffles (breakfast), Vegetable Soup (lunch), Potato Gratin (dinner)] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.