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

问题描述 投票:0回答:2

给出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个映射组合到包含Food对象(列表)的单个列表。

//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流来实现吗?任何解决方案将不胜感激。

java java-8 stream
2个回答
1
投票

您可以执行以下操作:

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());

    return foods;

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.