[英]Populate Arraylist in Java8 declarative style instead of doing it iteratively
Is is possible to write the following code using a stream
and map
?是否可以使用stream
和map
编写以下代码?
public List<Cake> getChocolateAmmountPerCakeHelperMethod(List<BigDecimal> chocolateAmounts) {
List<Cake> cakes = new ArrayList<>();
chocolateAmounts.forEach(chocolateAmount -> {
Cake cake = new Cake();
cake.setChocolateAmount(chocolateAmount);
cakes.add(cake);
});
return cakes;
}
Andronicus' answer is correct and best when applicable, but if you can't or don't want to modify the existing classes, you could achieve it like this: Andronicus 的答案在适用时是正确和最佳的,但如果您不能或不想修改现有类,则可以这样实现:
public List<Cake> getChocolateAmmountPerCakeHelperMethod(List<BigDecimal> chocolateAmounts) {
return chocolateAmounts.stream()
.map(anAmount -> {
Cake cake = new Cake();
cake.setChocolateAmount(anAmount);
return cake;
}).collect(Collectors.toList());
}
This lets you map over each item in the list with a block of code, then collect the mapped results into a new list.这使您可以使用代码块映射列表中的每个项目,然后将映射结果收集到一个新列表中。
You can create a constructor for Cake
, that takes chocolateAmount
as a parameter of type BigDecimal
.您可以为Cake
创建一个构造函数,它将chocolateAmount
作为BigDecimal
类型的参数。 Then, you can use map
in the following way:然后,您可以通过以下方式使用map
:
return chocolateAmounts.stream()
.map(Cake::new) // here
.collect(Collectors.toList());
PS: The answer assumes, that you can modify Cake
's code. PS:答案假设您可以修改Cake
的代码。
Here is a fully working example.这是一个完全有效的示例。 If you only need the main snippet of code, then go here .如果您只需要主要代码片段,请转到此处。
In the main method, I used an IntStream
& converted them into a list of BigDecimal which will be used as chocolate amounts.在主要方法中,我使用了一个IntStream
并将它们转换为一个 BigDecimal 列表,该列表将用作巧克力量。
In the getChocolateAmmountPerCakeHelperMethod
, I create a list of Cake objects from the chocolate amounts.在getChocolateAmmountPerCakeHelperMethod
,我根据巧克力数量创建了一个 Cake 对象列表。 This is done by streaming the chocolate amounts, mapping ie converting each amount into a Cake object with right chocolate amount and then collecting all the Cakes into a list.这是通过流式传输巧克力量来完成的,映射即将每个量转换为具有正确巧克力量的 Cake 对象,然后将所有 Cakes 收集到一个列表中。 As an aside, I am printing all the Cake objects.顺便说一句,我正在打印所有 Cake 对象。
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CakeMaker {
public List<Cake> getChocolateAmmountPerCakeHelperMethod(List<BigDecimal> chocolateAmounts) {
List<Cake> cakes = chocolateAmounts
.stream()
//If we had constructor Cake(BigDecimal choco), then map(...) code would be Cake::new OR choco -> new Cake(choco)
.map(choco -> { Cake cake = new Cake(); cake.setChocolateAmount(choco); return cake;} )
.collect(Collectors.toList());
return cakes;
}
public static void main(String [] args){
List<BigDecimal> chocos = IntStream
.rangeClosed(5, 10)
.mapToObj( i -> BigDecimal.valueOf(i) )
.collect(Collectors.toList());
CakeMaker cm = new CakeMaker();
List<Cake> cakes = cm.getChocolateAmmountPerCakeHelperMethod(chocos);
cakes.forEach(System.out::println);
}
}
Updated Cake class code:更新蛋糕类代码:
import java.math.BigDecimal;
public class Cake {
private BigDecimal chocolateAmount;
public Cake() {}
public Cake(BigDecimal chocolateAmount) {
this.chocolateAmount = chocolateAmount;
}
public void setChocolateAmount(BigDecimal chocolateAmount) {
this.chocolateAmount = chocolateAmount;
}
@Override
public String toString(){
return "CAKE [ choco = " + chocolateAmount + "]";
}
}
Output:输出:
CAKE [ choco = 5]
CAKE [ choco = 6]
CAKE [ choco = 7]
CAKE [ choco = 8]
CAKE [ choco = 9]
CAKE [ choco = 10]
As addendum to Andronicus' correct answer :作为安德洛尼克斯正确答案的附录:
if you can't create the constructor because you can't modify sources, you could add a helper method:如果由于无法修改源而无法创建构造函数,则可以添加辅助方法:
static Cake createCakeForChocolateAmount(BigDecimal amount){
Cake cake = new Cake();
cake.setChocolateAmount(anAmount);
return cake;
}
That would change his code to this:这会将他的代码更改为:
return chocolateAmounts.stream()
.map(ThisClass::createCakeForChocolateAmount)
.collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.