我想用java streams在对象内部做一个列表或列表映射。

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

阅读 "Java 8 In Action",我创建了真实的生活练习,把对象,例如在消息队列。

我有一个对象,里面有一个列表。我想通过对象List中的元素将这些对象与流组成一个List.我需要Map或至少是List,见示例。

例子。

Beverage cola = new Beverage("Cola", Arrays.asList("cubes", "lemon"));
Beverage tea = new Beverage("Tea", Arrays.asList("sugar", "milk", "lemon"));


class Beverage{
    String name;
    List<String> adds;

    public Beverage(String name, List<String> adds) {
        this.name = name;
        this.adds = adds;
    }

    public String getName() {
        return name;
    }

    public List<String> getAdds() {
        return adds;
    }

    @Override
    public String toString() {
        return "Beverage{" +
            "name='" + name + '\'' +
            ", adds=" + adds +
            '}';
    }
}

我有这个:

final Map<List<String>, Beverage> collect = beveragesMenu.stream()
.collect(Collectors.toMap(Beverage::getAdds, beverage -> beverage));

它产生的结果是:

Key: [cubes, lemon]: Beverage{name='Cola', adds=[cubes, lemon]}
Key: [sugar, milk, lemon]: Beverage{name='Tea', adds=[sugar, milk, lemon]}

但我需要Map:

Key: [cubes]: Beverage{name='Cola', adds=[cubes, lemon]}
Key: [sugar,]: Beverage{name='Tea', adds=[sugar, milk, lemon]}
Key: [milk]: Beverage{name='Tea', adds=[sugar, milk, lemon]}
Key: [lemon]: Beverage{name='Tea', adds=[sugar, milk, lemon]},Beverage{name='Cola', adds=[cubes, lemon]}

或和List。

Beverage{name='Cola', adds=[cubes]}
Beverage{name='Cola', adds=[lemon]}
Beverage{name='Tea', adds=[sugar]}
Beverage{name='Tea', adds=[milk]}
Beverage{name='Tea', adds=[lemon]}
java stream java-stream
1个回答
1
投票

假设你有一个饮料的列表,比如。

List<Beverage> myBeverageList = List.of(new Beverage("Cola", Arrays.asList("cubes", "lemon")),
                                        new Beverage("Tea", Arrays.asList("sugar", "milk", "lemon"))
                                       );

你可以生成一个成分到饮料列表的映射。

Map<String, List<Beverage>> ingredientsToBeverageMapping = myBeverageList.stream()
    .flatMap(bev -> bev.getAdds().stream()
            .map(ingr -> new AbstractMap.SimpleEntry<>(ingr, bev)))
    .collect(Collectors.groupingBy(Map.Entry::getKey,
            Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

1
投票

对于一些东西,像这样的,我建议你用一个 平面图

代码:

public List<Beverage> beverages = Arrays.asList(cola, tea);
beverages.stream()
         .flatMap(beverage -> beverage.getAdds().stream().map(add -> new Beverage(beverage.getName(), Collections.singletonList(add))))
         .collect(Collectors.toList())

输出。

[
    Beverage{name='Cola', adds=[cubes]}, 
    Beverage{name='Cola', adds=[lemon]}, 
    Beverage{name='Tea', adds=[sugar]}, 
    Beverage{name='Tea', adds=[milk]}, 
    Beverage{name='Tea', adds=[lemon]}
]

1
投票

你可以做这样的事情。基本上每一次 "添加",都会创建一个地图,然后将地图的每个条目放到列表中。你可以创建新的 Beverage 的对象。

    public static void main(String[] args) {
        Beverage cola = new Beverage("Cola", Arrays.asList("cubes", "lemon"));
        Beverage tea = new Beverage("Tea", Arrays.asList("sugar", "milk", "lemon"));

        Stream.of(cola, tea)
                .map(Main::mapBeverage)
                .flatMap(map -> map.entrySet().stream())
                .collect(Collectors.toList())
                .forEach(System.out::println);

    }

    private static Map<String, Beverage> mapBeverage(Beverage beverage) {
        return beverage.getAdds()
                .stream()
                .collect(Collectors.toMap(
                        add -> add,
                        add -> beverage
                ));
    }

它输出:

lemon=Beverage{name='Cola', adds=[cubes, lemon]}
cubes=Beverage{name='Cola', adds=[cubes, lemon]}
lemon=Beverage{name='Tea', adds=[sugar, milk, lemon]}
milk=Beverage{name='Tea', adds=[sugar, milk, lemon]}
sugar=Beverage{name='Tea', adds=[sugar, milk, lemon]}
© www.soinside.com 2019 - 2024. All rights reserved.