java - Java:对象池和哈希集
问题描述
让我们假设以下课程...
class Foo {
private Bar1 bar1;
private Bar2 bar2;
// many other fields
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Foo foo = (Foo) o;
if (!bar1.equals(foo.getBar1()) return false;
if (!bar2.equals(foo.getBar2()) return false;
// etc...
}
@Override
public int hashCode() {
int result = bar1.hashCode();
result = 31 * result + bar2.hashCode();
// etc...
}
// setters & getters follow...
}
每分钟创建、处理数千个 Foo 实例,然后在池中回收。工作流程如下:
Set<Foo> foos = new THashSet<>();
while (there-is-data) {
String serializedDataFromApi = api.getData();
Set<Foo> buffer = pool.deserializeAndCreate(serializedDataFromApi);
foos.addAll(buffer);
}
processor.process(foos);
pool.recycle(foos);
问题是不同缓冲区之间可能存在重复的 foo 对象(具有相同的值)。这些被具体化为 Foo 的不同实例,但是在调用 foos.addAll(buffer) 时它们被认为是相等的。
我的问题是:
- 这些“重复”实例发生了什么?
- 他们“丢失”并收集垃圾了吗?
- 如果我想将这些实例保留在池中,那么在使用 addAll 和回收实例插入之前测试重复项的最有效方法是什么?
解决方案
这些“重复”实例发生了什么?他们“丢失”并收集垃圾了吗?
是的,这些将在当前迭代while (there-is-data)
完成后立即有资格进行 GC
如果我想将这些实例保留在池中,那么在使用 addAll 和回收实例插入之前测试重复项的最有效方法是什么?
Set.add
true
如果元素被插入并且false
它是重复的,则返回。所以你可以addAll
用
for (Foo f : buffer) {
if (!foos.add(f)) {
// handle duplicate
}
}
不会对性能造成影响,因为addAll
这样做 - 迭代并一一添加。
推荐阅读
- vue.js - vue - 孙子的 $emit
- swift - 从类到 swift UI 类
- docker - 带有 ssl 的 docker 的 nginx-proxy 的 Websockets 请求失败
- angular - 如何为选择更改功能的下拉列表编写单元测试
- node.js - 执行插入后如何从mysql中获取某些值-node js
- django - django过滤优化
- php - 如何启动多个会话
- sql - MS Access SQL – 如何计算一个表中的数字在另一个表的字符串中出现的次数
- vnc - 有没有办法将 VNC 连接限制为 TrueNAS 虚拟机中的一个用户?
- extjs - ExtJS 7.2 动态更改整个应用程序“字体系列”