如何使用 Java 8 根据条件从项目页面内的集合中删除元素
How to remove an element from a Set inside a Page of items based on a Condition using Java 8
我有一个 Page
of Farmers
来自 JPA 存储库 调用 findAll
方法。每个 Farmer 由 Set
个 Farms
组成,它们也像这样进入存储库调用:
public class Farmer {
private String name;
@ManyToMany
@JoinTable(name = "farmer_asset", joinColumns = @JoinColumn(name = "farmer_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "asset_id", referencedColumnName = "id"))
private Set<Asset> assets;
}
Asset
有一个叫isActive
的属性表示资产是否活跃;
在我 Farmers
的 Page
中,我只想 select 活跃的农民资产;
我试过
@WhereJoinTable(clause = "is_active ='true'")
但是,我了解到 is_active
属性 应该处于中间 ManyToMany 关系 Table farmer_asset
现在我无法更改实体结构,并使用 @WhereJoinTable(clause = "is_active ='true'")
。
因此,我想到在进行 JPA 调用后尝试过滤这些值。
但是,遍历每个 Farmer
,然后删除 inActive Assets
,然后将其添加回页面并维护页面元素似乎过于性能繁重的操作。
我尝试使用正常的 Java 代码,看起来像这样:
Page<Farmer> farmers = farmerRepository.findAll(pageable);
List<Farmer> farmersList = new LinkedList<>();
for (FarmerDto eachFarmer : farmers.getContent()) {
Set<Asset> eachFarmerAssets =
eachFarmer.getAssets();
eachFarmerAssets.removeIf(e ->
!e.getIsActive());
eachFarmer.setAssets(eachFarmerAssets);
farmersList.add(eachFarmer);
}
return new PageImpl<FarmerDto>(farmersList, pageable, farmers.getTotalElements());
我想这样做 Java 8 使用流,但我无法迭代列表并更改其元素,而元素又是 Set<Asset>
来这里寻求一些建议。
提前致谢。
您实际上不会将相同的引用重新分配给 Set<Asset>
,因为即使集合已被修改,它仍然是特定农民“已知”的同一对象。
并且您绝对不需要流来完成此任务。文档建议在设计流 pipe-lines.
时避免有状态操作和 side-effects
相反,您可以在列表上使用 forEach()
方法:
Page<Farmer> farmers = farmerRepository.findAll(pageable);
List<Farmer> farmersList = new farmers.getContent();
farmersList.forEach(farmer -> farmer.getAssets()
.removeIf(e -> !e.getIsActive()));
您必须按照以下步骤操作:
- 检索农民实体列表
- 将实体列表转换为 farmer dtos 列表
- 每个农民 dto
- 填写数据
- 放入活跃的断言列表
List<Farmer> farmers = farmerRepository.findAll(pageable).getContent(); //1
List<FarmerDto> farmersList = farmers.stream() // 2
.map(farmer -> { // 3
FarmerDto farmerDto = new FarmerDto();
// fill farmerDto 3.1
farmerDto.setAssets(farmer.getAssets().stream().filter(Farmer::getIsActive()).toList()); //3.2
return farmerDto;
}).toList();
return new PageImpl<FarmerDto>(farmersList, pageable, farmers.getTotalElements());
我有一个 Page
of Farmers
来自 JPA 存储库 调用 findAll
方法。每个 Farmer 由 Set
个 Farms
组成,它们也像这样进入存储库调用:
public class Farmer {
private String name;
@ManyToMany
@JoinTable(name = "farmer_asset", joinColumns = @JoinColumn(name = "farmer_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "asset_id", referencedColumnName = "id"))
private Set<Asset> assets;
}
Asset
有一个叫isActive
的属性表示资产是否活跃;
在我 Farmers
的 Page
中,我只想 select 活跃的农民资产;
我试过
@WhereJoinTable(clause = "is_active ='true'")
但是,我了解到 is_active
属性 应该处于中间 ManyToMany 关系 Table farmer_asset
现在我无法更改实体结构,并使用 @WhereJoinTable(clause = "is_active ='true'")
。
因此,我想到在进行 JPA 调用后尝试过滤这些值。
但是,遍历每个 Farmer
,然后删除 inActive Assets
,然后将其添加回页面并维护页面元素似乎过于性能繁重的操作。
我尝试使用正常的 Java 代码,看起来像这样:
Page<Farmer> farmers = farmerRepository.findAll(pageable);
List<Farmer> farmersList = new LinkedList<>();
for (FarmerDto eachFarmer : farmers.getContent()) {
Set<Asset> eachFarmerAssets =
eachFarmer.getAssets();
eachFarmerAssets.removeIf(e ->
!e.getIsActive());
eachFarmer.setAssets(eachFarmerAssets);
farmersList.add(eachFarmer);
}
return new PageImpl<FarmerDto>(farmersList, pageable, farmers.getTotalElements());
我想这样做 Java 8 使用流,但我无法迭代列表并更改其元素,而元素又是 Set<Asset>
来这里寻求一些建议。
提前致谢。
您实际上不会将相同的引用重新分配给 Set<Asset>
,因为即使集合已被修改,它仍然是特定农民“已知”的同一对象。
并且您绝对不需要流来完成此任务。文档建议在设计流 pipe-lines.
时避免有状态操作和 side-effects相反,您可以在列表上使用 forEach()
方法:
Page<Farmer> farmers = farmerRepository.findAll(pageable);
List<Farmer> farmersList = new farmers.getContent();
farmersList.forEach(farmer -> farmer.getAssets()
.removeIf(e -> !e.getIsActive()));
您必须按照以下步骤操作:
- 检索农民实体列表
- 将实体列表转换为 farmer dtos 列表
- 每个农民 dto
- 填写数据
- 放入活跃的断言列表
List<Farmer> farmers = farmerRepository.findAll(pageable).getContent(); //1
List<FarmerDto> farmersList = farmers.stream() // 2
.map(farmer -> { // 3
FarmerDto farmerDto = new FarmerDto();
// fill farmerDto 3.1
farmerDto.setAssets(farmer.getAssets().stream().filter(Farmer::getIsActive()).toList()); //3.2
return farmerDto;
}).toList();
return new PageImpl<FarmerDto>(farmersList, pageable, farmers.getTotalElements());