如何将常规 for 循环转换为 Java 8 流

编码器

我有课ProductRegionAllocation

class Product{

int id;
String region;
int price;

Product(int I'd, int price,String region){
this.id = id;
this.price = price;
this.region = region;
}
 //getters for id and price
}

List<Product> list = new ArrayList();
list.add(1, 30, "LDN")
list.add(2, 25, "NYK")

class RegionAllocation{
int price;
int alloQty;

RegionAllocation(Product p)
this.price = p.getPrice();
}

RegionAllocation allocate(int a){
this.alloQty+=a;
return this;
}

}

我想使用流编写一个函数,它流过产品,并为每个产品创建 RegionAllocation 对象并根据价格值设置分配函数

List<RegionAllocation> reg = new ArrayList();
for(Product p : products) {
    RegionAllocation r = new RegionAllocation(p); 

    if(p.getRegion().equals("LDN") {
        r.allocate(0);
    } else{          
        r.allocate(p.getPrice()*5)
    }
    reg.add(r);
    }

return reg;

我想使用 java 8 流在上面写。

佩皮诺

将常规循环转换为Streams 时,最好先确定每段代码的作用。

如果我们查看您的 for 循环,我们可以推断出以下功能:

// Creation of an empty list
List<RegionAllocation> reg = new ArrayList();
// Loop over the products
for(Product p : products) {
    // Create a new RegionAllocation
    RegionAllocation r = new RegionAllocation(p); 

    // Allocate the RegionAllocation
    if(p.getRegion().equals("LDN") {
        r.allocate(0);
    } else{          
        r.allocate(p.getPrice()*5)
    }
    // Add the RegionAllocation to the list
    reg.add(r);
}

return reg;

由此我们已经可以看到 for 循环中的代码由两个不同的部分组成;RegionAllocation从 a创建和分配一个新Product并将这个新添加RegionAllocation到列表中。

在这种情况下,第一步是将 的创建和分配提取RegionAllocation到一个单独的方法中(我已将您的原始代码包装在一个方法中并调用它createRegionAllocations

public List<RegionAllocation> createRegionAllocations(List<Product> products) {
    List<RegionAllocation> reg = new ArrayList();
    for(Product p : products) {
        RegionAllocation r = createRegionAllocation(p);
        reg.add(r);
    }

    return reg;
}

private RegionAllocation createRegionAllocation(Product p) {
    RegionAllocation r = new RegionAllocation(p); 

    if(p.getRegion().equals("LDN") {
        r.allocate(0);
    } else{          
        r.allocate(p.getPrice()*5)
    }

    return r;
}

现在我们可以将循环转换为流。循环的“for”部分

for (Product p : products)

变成

products.stream() // Stream<Product>

也就是Stream<Product>产品流。

该方法从 acreateRegionAllocation创建 a RegionAllocationProduct因此它将一种类型 ( Product) 转换为另一种类型 ( RegionAllocation)。这就是该map方法对流所做的事情它的签名是

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

其中Tmap调用流的类型,R是新类型。所以在你的情况下,我们现在可以做

products.stream() // Stream<Product>
    .map(p -> createRegionAllocation(p)) // Stream<RegionAllocation>

现在最后一步是创建流列表。这就是collect方法的用处。有很多方法可以收集流,但是对于这种情况,当我们收集时,我们会这样做

products.stream() // Stream<Product>
    .map(p -> createRegionAllocation(p)) // Stream<RegionAllocation>
    .collect(Collectors.toList()) // List<RegionAllocation>

除了Collectors.toList()(收集到 a List)你还可以做例如Collectors.toSet()(收集到 a Set)或一大堆其他自定义收集器,如果你需要的话。但是对于Lists 你只需要记住.collect(Collectors.toList()).

最后,我们可以使用方法引用createRegionAllocation

products.stream() // Stream<Product>
    .map(this::createRegionAllocation) // Stream<RegionAllocation>
    .collect(Collectors.toList()) // List<RegionAllocation>

所以当我们把它们放在一起时,我们得到

public List<RegionAllocation> createRegionAllocations(List<Product> products) {
    return products.stream()
        .map(this::createRegionAllocation)
        .collect(Collectors.toList());
}

private RegionAllocation createRegionAllocation(Product p) {
    RegionAllocation r = new RegionAllocation(p); 

    if(p.getRegion().equals("LDN") {
        r.allocate(0);
    } else{          
        r.allocate(p.getPrice()*5)
    }

    return r;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章