比较来自 findAll() 的 java 元素
compare java element from a findAll()
我必须从从 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);
}
但是,不会从列表中删除重复项,然后在我不想删除时保留它们。
为什么不使用以 prospectNumber 作为值的 HashSet。 HashSet 不能包含重复的键。之后,您可以遍历 List 并删除所有重复元素。希望对您有所帮助!
你可以使用像
这样的东西
List<Prospection> all = prospectionRepository.findAll();
Set<Object> prospectNumbers = new HashSet<Object>();
Iterator<Prospection> it = all.iterator();
while (it.hasNext()) {
Prospection item = iterator.next();
Object itemNumer = item.getProspectNumber();
if (prospectNumbers.contains(itemNumber)) {
it.remove();
} else {
prospectNumbers.add(itemNumber);
}
}
问题编辑
在聊天中对话后,必须考虑其他参数:
- multiples
Prospect
may have the same prospect number
but they do have an unique primary key in the database. Consequently, the duplicate filter cannot rely on the Prospect
equality
- a
Prospect
has a visited status which defined whether the Prospect
has been contacted by the company or not. The two main status are NEW
and MET
. Only one Prospect
can be MET
. Other duplicates (with the same prospect number
) can only be NEW
算法
问题需要额外的步骤才能解决:
- 潜在客户需要按
prospect number
分组。在此阶段,我们将进行 <ProspectNumber, List<Prospect>>
映射。但是,List<Prospect>
必须根据之前定义的规则以单个元素结尾
- 在列表中,如果未满足潜在客户 AND 发现另一个具有 met 状态的潜在客户,则第一个潜在客户将被丢弃
因此,将按照以下规则生成列表:
- 如果潜在客户在潜在客户编号方面没有重复,则无论其状态如何都将保留
- 如果潜在客户的潜在客户编号重复,则只保留
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()
其实return一个Collection
。因此,如果您的 prospectionRepository.save(...)
可以接受 Collection
(不仅是 List
),您可以走得更快。我还使用以下同义词:
- static method reference:
Prospect::getProspectNumber
是 Function
等同于 prospect -> prospect.getProspectNumber()
Function.identity()
:等价于prospect -> prospect
- 三元运算符:return是同一个东西,只是写法不同
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);
我必须从从 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);
}
但是,不会从列表中删除重复项,然后在我不想删除时保留它们。
为什么不使用以 prospectNumber 作为值的 HashSet。 HashSet 不能包含重复的键。之后,您可以遍历 List 并删除所有重复元素。希望对您有所帮助!
你可以使用像
这样的东西List<Prospection> all = prospectionRepository.findAll();
Set<Object> prospectNumbers = new HashSet<Object>();
Iterator<Prospection> it = all.iterator();
while (it.hasNext()) {
Prospection item = iterator.next();
Object itemNumer = item.getProspectNumber();
if (prospectNumbers.contains(itemNumber)) {
it.remove();
} else {
prospectNumbers.add(itemNumber);
}
}
问题编辑
在聊天中对话后,必须考虑其他参数:
- multiples
Prospect
may have the sameprospect number
but they do have an unique primary key in the database. Consequently, the duplicate filter cannot rely on theProspect
equality- a
Prospect
has a visited status which defined whether theProspect
has been contacted by the company or not. The two main status areNEW
andMET
. Only oneProspect
can beMET
. Other duplicates (with the sameprospect number
) can only beNEW
算法
问题需要额外的步骤才能解决:
- 潜在客户需要按
prospect number
分组。在此阶段,我们将进行<ProspectNumber, List<Prospect>>
映射。但是,List<Prospect>
必须根据之前定义的规则以单个元素结尾 - 在列表中,如果未满足潜在客户 AND 发现另一个具有 met 状态的潜在客户,则第一个潜在客户将被丢弃
因此,将按照以下规则生成列表:
- 如果潜在客户在潜在客户编号方面没有重复,则无论其状态如何都将保留
- 如果潜在客户的潜在客户编号重复,则只保留
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()
其实return一个Collection
。因此,如果您的 prospectionRepository.save(...)
可以接受 Collection
(不仅是 List
),您可以走得更快。我还使用以下同义词:
- static method reference:
Prospect::getProspectNumber
是Function
等同于prospect -> prospect.getProspectNumber()
Function.identity()
:等价于prospect -> prospect
- 三元运算符:return是同一个东西,只是写法不同
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);