我有课Product
和RegionAllocation
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 流在上面写。
将常规循环转换为Stream
s 时,最好先确定每段代码的作用。
如果我们查看您的 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 RegionAllocation
,Product
因此它将一种类型 ( Product
) 转换为另一种类型 ( RegionAllocation
)。这就是该map
方法对流所做的事情。它的签名是
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
其中T
是map
调用流的类型,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
)或一大堆其他自定义收集器,如果你需要的话。但是对于List
s 你只需要记住.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] 删除。
我来说两句