当前位置:网站首页>List获取差集产生的问题
List获取差集产生的问题
2022-07-30 03:28:00 【沛沛老爹】
背景
在批量保存数据的时候,需要和数据库进行比对。如果当前数据存在则从List集合中删除。
List批量删除的话,一般都会考虑使用removeAll。
操作流程如下:
1、将现有批量数据的外部唯一字段和数据库中的数据进行匹配,返回现有存在的List对象
2、使用removeAll功能,批量删除,取得当前差集。
使用removeAll功能后,在批量保存的时候,还是直接导致了数据重复。
Api 说明
操作类型 | 方法 | 说明 |
| 交集 | listA.retainAll(listB) | 调用方法后ListA变为两个集合的交集,ListB不变 |
| 差集 | listA.removeAll(listB) | 调用方法后ListA变为两个集合的差集,ListB不变 |
| 并集 | 1.listA.removeAll(listB) 2.listA.addAll(listB) | 去重,先取差集再并集。ListA变为两个集合的并集,ListB不变 |
removeAll源码
说啥都是虚的,翻removeAll源码牌子。
public boolean removeAll(Collection<?> c) {
return batchRemove(c, false, 0, size);
}
...
boolean batchRemove(Collection<?> c, boolean complement,
final int from, final int end) {
Objects.requireNonNull(c);
final Object[] es = elementData;
int r;
// Optimize for initial run of survivors
for (r = from;; r++) {
if (r == end)
return false;
if (c.contains(es[r]) != complement)
break;
}
int w = r++;
try {
for (Object e; r < end; r++)
if (c.contains(e = es[r]) == complement)
es[w++] = e;
} catch (Throwable ex) {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
System.arraycopy(es, r, es, w, end - r);
w += end - r;
throw ex;
} finally {
modCount += end - w;
shiftTailOverGap(es, w, end);
}
return true;
}
我们可以看到,需要循环比较每个对象。
for (r = from;; r++) {
if (r == end)
return false;
if (c.contains(es[r]) != complement)
break;
}从数据库查出来的数据,包含了ID等其它字段。这样两个对象的属性就不一样了。所以会返回false。这样就达不到去重的目的了。
自定义对象就可以使用下面JDK8+的Stream方式去去重了。
将已经在库的数据(exitList)和需要保存的数据(entityList)匹配,将不存在库里的挑出来放到新的List(saveDataEntityList)中。
伪代码如下:
saveDataEntityList = entityList.stream().filter(f -> !exitList.stream().map(Entity::getId).collect(Collectors.toList()).contains(f.getId())
).collect(Collectors.toList());经过测试,发现OK,没有重复数据了。
总结
removeAll适合子集完全匹配和基础类型的操作,建议在自定义对象的时候,不要使用removeAll方法,而是使用stream的方式。
边栏推荐
猜你喜欢

Public chains challenging the "Impossible Triangle"

开放地址法哈希实现——线性探测法

Redis(十) - Redission原理与实践

The relationship between the number of Oracle processes and the number of sessions

状态空间表示

基于数据驱动故障预测的多台电力设备预测性维护调度

复合类型--引用,指针

selenium应用之拉勾简历邀约数据抓取与分析
![[Flink] How to determine the cluster planning size from development to production launch?](/img/7a/52dae876a50980c5055be131c2254b.png)
[Flink] How to determine the cluster planning size from development to production launch?

WPF 学习笔记《WPF布局基础》
随机推荐
复星医药募资44.84亿:高毅资产认购20亿 成第三大股东
BindingExpression path error: ‘selectMenusList‘ property not found on ‘object‘ ‘‘ViewModel“
SQL Server数据类型转换函数cast()和convert()详解
Leetcode.234 判断回文链表(双指针/快慢指针)
A. Strange Birthday Party- Codeforces Round #694 (Div. 1)
3.nodejs--modularization
复合类型--引用,指针
Record NLP various resource URLs
微服务进阶 Cloud Alibaba
nSoftware.PowerShell.Server.2020
解决导航栏变黑色
Simple Operations on Sequence
联邦学习综述(一)——联邦学习的背景、定义及价值
MyCat中对分库分表、ER表、全局表、分片规则、全局序列等的实现与基本使用操作
(RCE)远程代码/命令执行漏洞漏洞练习
一本通1922——乒乓球
REUSE_ALV_GRID_DISPLAY详解
sublime text 3 设置
[Andrioid开发] Splash界面/用户协议与隐私政策弹窗/界面开发
gnss rtcm rtklib Ntrip...
