我必须从CrudRepository检索的对象列表中删除重复项。
我做到了:
if (!prospectionRepository.findAll().isEmpty()) {
List<Prospection> all = prospectionRepository.findAll();
for (int i = 0; i < all.size()-1; i++) {
for (int k = i+1;k < all.size(); k++) {
if (all.get(i).getProspectNumber() == all.get(k).getProspectNumber()) {
all.remove(all.get(i));
}
}
}
prospectionRepository.save(all);
}
但是,重复项不会从列表中删除,当我不想重复时,它们会保留下来。
最佳答案
问题编辑
在聊天中交谈后,必须考虑其他参数:
Prospect
可以具有相同的prospect number
,但它们在数据库中确实具有唯一的主键。因此,重复过滤器不能依赖Prospect
等式Prospect
具有已访问状态,该状态定义了公司是否已联系Prospect
。两种主要状态是NEW
和MET
。 Prospect
只能是一个MET
。其他重复项(具有相同的prospect number
)只能是NEW
算法
该问题需要另外解决一个步骤:
prospect number
分组。在这一阶段,我们将进行<ProspectNumber, List<Prospect>>
映射。但是,List<Prospect>
必须根据早期因此,将使用以下规则生成列表:
met
一个met
,则满足任意一个:Stream
不保证以列表顺序循环。 码
诀窍是通过
Map
来完成,因为密钥将保持唯一性。如果您的预期编号是特定类型,则将假定正确定义了equals()
和hashCode()
。免责声明:代码未经测试
List<Prospection> all = prospectionRepository.findAll().stream()
// we instantiate here a Map<ProspectNumber, Prospect>
// There is no need to have a Map<ProspectNumber, List<Propect>>
// as the merge function will do the sorting for us
.collect(Collectors.toMap(
// Key: use the prospect number
prospect -> prospect.getProspectNumber(),
// Value: use the propect object itself
prospect -> prospect,
// Merge function: two prospects with the same prospect number
// are found: keep the one with the MET status or the first one
(oldProspect, newProspect) -> {
if(oldProspect.getStatus() == MET){
return oldProspect;
} else if (newProspect.getStatus() == MET){
return newProspect;
} else{
// return the first one, arbitrary decision
return oldProspect;
}
}
))
// get map values only
.values()
// stream it in order to collect its as a List
.stream()
.collect(Collectors.toList());
prospectionRepository.save(all);
Map.values()
实际上返回Collection
。因此,如果您的prospectionRepository.save(...)
可以接受Collection
(不仅是List
),那么您可以走得更快。我还使用以下同义词:Prospect::getProspectNumber
是与Function
等效的prospect -> prospect.getProspectNumber()
Function.identity()
:等同于prospect -> prospect
Collection<Prospection> all = prospectionRepository.findAll().stream()
.collect(Collectors.toMap(
Prospect::getProspectNumber,
Function.identity(),
(oldProspect, newProspect) -> newProspect.getStatus() == MET ? newProspect : oldProspect
)).values();
prospectionRepository.save(all);
供您参考,如果两个具有相同
Prospection
的ProspectNumber
相等,那么一个简单的 distinct()
就足够了:List<Prospection> all = prospectionRepository.findAll()
.stream()
.distinct()
.collect(Collectors.toList());
prospectionRepository.save(all);