简体   繁体   English

以 Java8 声明式样式填充 Arraylist 而不是迭代地进行

[英]Populate Arraylist in Java8 declarative style instead of doing it iteratively

Is is possible to write the following code using a stream and map ?是否可以使用streammap编写以下代码?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM