英文:
How do I sort an Arraylist so its collection is sorted by a list of values
问题
我有一个包含食谱的 ArrayList,每个食谱都包含一系列的配料。这些食谱在 Android 应用的 UI 列表中显示,用户希望根据他们最喜欢的配料对列表进行排序。
例如,这是他们最喜欢的配料列表:
1 - 奶酪
2 - 马铃薯
3 - 金枪鱼
4 - 鸡肉
因此,食谱列表应该首先显示所有包含奶酪的配料,然后是马铃薯等等。如何使用 Java 的 stream()
实现这一点?
以下是我目前的模型类结构
public class Recipe {
String[] ingredients;
private String description;
private String title;
public String[] getIngredients() {
return ingredients;
}
public void setIngredients(String[] ingredients) {
this.ingredients = ingredients;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
public class Ingredient {
String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
英文:
I have an Arraylist which contains recipies and each recipe contains a list of ingredients. The recipies is shown in a UI list of an Android app and the useres wants to sort the list based on the ingredients they like most.
For example this is the list of ingredients they like most
1 - Cheese
2 - Potato
3 - Tuna
4 - Chicken
So the list of recipies shall show first all the ingredients that contains cheese and then potato etc.
How do I archive this with java stream()
?
Here is how my model classes is at the moment
public class Recipe {
String[] ingredients;
private String description;
private String title;
public String[] getIngredients() {
return ingredients;
}
public void setIngredients(String[] ingredients) {
this.ingredients = ingredients;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
.
public class Ingredient {
String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
答案1
得分: 0
你可以创建 comparatorPotato
和 comparatorCheese
,然后基于它们进行排序。
static class Recipie {
List<String> list;
public Recipie(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return list.toString();
}
}
public static void main(String[] args) {
List<Recipie> recipies = new ArrayList<>();
recipies.add(new Recipie(Arrays.asList("Cheese", "Potato", "Onions")));
recipies.add(new Recipie(Arrays.asList("Tuna", "Potato", "Chicken")));
recipies.add(new Recipie(Arrays.asList("Potato", "Cheese")));
recipies.add(new Recipie(Arrays.asList("Chicken")));
recipies.add(new Recipie(Arrays.asList("Chicken", "Potato")));
recipies.add(new Recipie(Arrays.asList("Cheese", "Tomato")));
List<Recipie> result = recipies.stream().sorted(Comparator.comparing(r -> !r.list.contains("Potato")))
.sorted(Comparator.comparing(r -> !r.list.contains("Cheese"))).collect(Collectors.toList());
System.out.println(result);
}
输出:
[[Cheese, Potato, Onions], [Potato, Cheese], [Cheese, Tomato], [Tuna, Potato, Chicken], [Chicken, Potato], [Chicken]]
英文:
You can create comparatorPotato and comparatorCheese then sort based on them
static class Recipie {
List<String> list;
public Recipie(List<String> list) {
this.list = list;
}
@Override
public String toString() {
return list.toString();
}
}
public static void main(String[] args) {
List<Recipie> recipies = new ArrayList<>();
recipies.add(new Recipie(Arrays.asList("Cheese", "Potato", "Onions")));
recipies.add(new Recipie(Arrays.asList("Tuna", "Potato", "Chicken")));
recipies.add(new Recipie(Arrays.asList("Potato", "Cheese")));
recipies.add(new Recipie(Arrays.asList("Chicken")));
recipies.add(new Recipie(Arrays.asList("Chicken", "Potato")));
recipies.add(new Recipie(Arrays.asList("Cheese", "Tomato")));
List<Recipie> result = recipies.stream().sorted(Comparator.comparing(r -> !r.list.contains("Potato")))
.sorted(Comparator.comparing(r -> !r.list.contains("Cheese"))).collect(Collectors.toList());
System.out.println(result);
}
, output
[[Cheese, Potato, Onions], [Potato, Cheese], [Cheese, Tomato], [Tuna, Potato, Chicken], [Chicken, Potato], [Chicken]]
答案2
得分: 0
你的Recipe类没有使用你的Recipe类,所以你的模型可以被修改以使用Ingredient类。
public class Recipe {
List<Ingredient> ingredients;
...
}
你可以创建自己的Comparator来根据是否包含某个成分来排序Recipe。
public class ContainsIngredientComparator implements Comparator<Recipe> {
private Ingredient ingredient;
public ContainsIngredientComparator(Ingredient ingredient) {
this.ingredient = ingredient;
}
@Override
public int compare(Recipe r1, Recipe r2) {
if (r1.getIngredients().contains(ingredient)) {
if (r2.getIngredients().contains(ingredient)) {
return 0;
} else {
return -1;
}
} else if (r2.getIngredients().contains(ingredient)) {
return 1;
} else {
return 0;
}
}
}
现在,你可以为每个成分创建一个Comparator,并将所有比较器链接起来。你可以使用Stream API将喜爱的成分映射到比较器,并使用thenComparing
方法链接这些比较器:
Optional<ContainsIngredientComparator> favoritesComparator = favorites.stream()
.map(ContainsIngredientComparator::new)
.reduce((c1, c2) -> (ContainsIngredientComparator) c1.thenComparing(c2));
你可以使用结果比较器来对列表进行排序:
List<Recipe> recipeList = // ... 获取recipeList
if (favoritesComparator.isPresent()) {
recipeList.sort(favoritesComparator.get());
}
英文:
Your Recipe class is not using your Recipe class, so your model can be modified to use the Ingredient class.
public class Recipe {
List<Ingredient> ingredients;
...
}
You can create your own Comparator to sort if a Recipe has some ingredient.
public class ContainsIngredientComparator implements Comparator<Recipe> {
private Ingredient ingredient;
public ContainsIngredientComparator(Ingredient ingredient) {
this.ingredient = ingredient;
}
@Override
public int compare(Recipe r1, Recipe r2) {
if (r1.getIngredients().contains(ingredient)) {
if (r2.getIngredients().contains(ingredient)) {
return 0;
} else {
return -1;
}
} else if (r2.getIngredients().contains(ingredient)) {
return 1;
} else {
return 0;
}
}
}
Now, you can create a Comparator for each ingredient and chain all the comparators. You can use the Stream API to map the favorites ingredients to comparators and use thenComparing
to chain the comparators:
Optional<ContainsIngredientComparator> favoritesComparator = favorites.stream()
.map(ContainsIngredientComparator::new)
.reduce((c1, c2) -> (ContainsIngredientComparator) c1.thenComparing(c2));
You can use the result Comparator to sort the list:
List<Recipe> recipeList = // ... get the recipeList
if (favoritesComparator.isPresent()) {
recipeList.sort(favoritesComparator.get());
}
专注分享java语言的经验与见解,让所有开发者获益!
评论