使用 Java8 将两个映射合并到一个对象列表中



给定 2 个映射和一个对象

Map<Integer, List<String>> fruits = new HashMap<>();
fruits.put(1, Arrays.asList("apple", "banana"));
fruits.put(2, Arrays.asList("orange", "kiwi"));
Map<Integer, List<String>> veggies= new HashMap<>();
veggies.put(1, Arrays.asList("tomato", "potato"));
veggies.put(2, Arrays.asList("onion"));
Class Food
{
private id;
private List<String> fruitsList;
private List<String> veggiesList;
//getters and setters
}

我正在尝试将给定的 2 张地图组合到一个包含食物对象(列表(的列表。

//Used for explanation purpose
Food food1 = new Food();
food1.setId(1);
food1.setFruitsList(Arrays.asList("apple", "banana"));
food1.setVeggiesList(Arrays.asList("tomato", "potato"));
//Used for explanation purpose
Food food2 = new Food();
food2.setId(2);
food2.setFruitsList(Arrays.asList("orange", "kiwi"));
food2.setVeggiesList(Arrays.asList("onion"));
//Wanted this list of food
List<Food> foodList = new ArrayList();
foodList.add(food1);
foodList.add(food2);

我需要一份清单。 我们可以使用 Java8 流来实现这一点吗? 任何解决方案将不胜感激。

你可以做这样的事情:

List<Food> foodList = fruits.keySet().stream()
.concat(veggies.keySet().stream())
.distinct()
.map(id -> {
Food food = new Food();
food.setId(id);
food.setFruitsList(fruits.getOrDefault(id, new ArrayList<>()));
food.setVeggiesList(veggies.getOrDefault(id, new ArrayList<>()));
return food ;
})
.collect(Collectors.toList());

如果您的Food类有一个采用三个参数的构造函数,它会变得更加简洁:

List<Food> foodList = fruits.keySet().stream()
.concat(veggies.keySet().stream())
.distinct()
.map(id -> new Food(
id,
fruits.getOrDefault(id, new ArrayList<>()),
veggies.getOrDefault(id, new ArrayList<>())
)
.collect(Collectors.toList());

如果您知道两个地图中的 id 相同,则可以跳过.concat().distinct()步骤(非常昂贵(,只需使用get()而不是getOrDefault()

您也可以(在任何情况下(做

Set<Integer> allKeys = new HashSet<>(fruits.keySet());
allKeys.addAll(veggies.keySet());
List<Food> foodList = allKeys.stream()
.map(/* as before */)
.collect(Collectors.toList());

这不是一个"纯流"的解决方案,但可能更有效。

您可以合并两个密钥流,并使用不同的方法仅获取唯一密钥。

List<Food> foods = Stream.concat(fruits.keySet().stream() , veggies.keySet().stream())
.distinct()
.map(e -> new Food(e, fruits.get(e), veggies.get(e)))
.collect(Collectors.toList());

最新更新