Java流(Stream) API – 合并两个对象列表

huangapple go评论134阅读模式
英文:

Java Stream Api - merge two lists of objects

问题

我坐在这个简单的问题面前却无法理解... 也许现在太晚了 :) <br>
有一个简单的食物其中食物有id和数量想象购物清单):

public class Food {

private String id;

private Integer amount;

}


有一个包含一个“苹果”的食物列表,还有另一个包含一个“苹果”和一个“橙子”的食物列表。方法addFood应使用流API处理这两个列表,并返回一个包含两个“苹果”和一个“橙子”的列表:

List existingFood = new ArrayList();
existingFood.add(new Food("apple", 1));

List foodToAdd = new ArrayList();
foodToAdd.add(new Food("apple", 1));
foodToAdd.add(new Food("orange", 1));

List result = addFood(existingFood, foodToAdd);

// result应包含:
// 1. {"apple", 2}
// 2. {"orange", 1}


使用流API完成这个问题的最优雅方式是什么?
感谢您的帮助!
英文:

I am sitting in front of this simple problem and cannot get my head around...maybe its just too late Java流(Stream) API – 合并两个对象列表 <br>
There is a simple "Food" class where a Food has id and amount (imagine shopping list):

public class Food {

	private String id;

	private Integer amount;

}

There is a list of foods that contains one "apple" and another list of foods that contains an "apple" and an "orange". The method addFood should process both lists using stream api and return a list that contains two "apples" and one orange:

List&lt;Food&gt; existingFood = new ArrayList&lt;Food&gt;();
existingFood.add(new Food(&quot;apple&quot;, 1));

List&lt;Food&gt; foodToAdd = new ArrayList&lt;Food&gt;();
foodToAdd.add(new Food(&quot;apple&quot;, 1));
foodToAdd.add(new Food(&quot;orange&quot;, 1));

List&lt;Food&gt; result = addFood(existingFood, foodToAdd);
		
// result should contain:
// 1. {&quot;apple&quot;, 2}
// 2. {&quot;orange&quot;, 1} 

Whats the most elegant way to do that using stream api?
Thanks for your help!

答案1

得分: 0

你可以使用 Collectors.groupingBy 结合 Collectors.summingInt

List<Food> result = Stream.of(existingFood, foodToAdd)
        .flatMap(List::stream)
        .collect(Collectors.groupingBy(Food::getId, Collectors.summingInt(Food::getAmount)))
        .entrySet().stream()
        .map(e -> new Food(e.getKey(), e.getValue().intValue()))
        .collect(Collectors.toList());

输出:

Food(id=orange, amount=1)
Food(id=apple, amount=2)

注意:在DTO中,通常id是整数或长整型。在您的情况下,id可以是另一个名称,例如 name

英文:

You can use Collectors.groupingBy with Collectors.summingInt:

List&lt;Food&gt; result = Stream.of(existingFood, foodToAdd)
        .flatMap(List::stream)
        .collect(Collectors.groupingBy(Food::getId, Collectors.summingInt(Food::getAmount)))
        .entrySet().stream()
        .map(e -&gt; new Food(e.getKey(), e.getValue().intValue()))
        .collect(Collectors.toList());

Outputs

Food(id=orange, amount=1)
Food(id=apple, amount=2)

Note: the id in the DTOs generally be an Integer or Long, in you case the case the id can be another name, for example name

huangapple
  • 本文由 发表于 2020年6月29日 04:48:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/62628048.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定