使用包含相似值的两个 HashMap 保存内存

Preserving memory with two HashMaps that contain similar values

我正在按顺序将 2 个大型数据集加载到两个单独的 HashMap 中。 (数据集被序列化为许多 Record 对象,如下所示)。 HashMaps 是这样表示的,键是记录的 id:

Map<Long, Record> recordMapA = new HashMap<>();
Map<Long, Record> recordMapB = new HashMap<>();

记录对象如下所示:

class Record {
  Long id; 
  Long timestamp; 
  String category;
  String location;  
}    

在很多情况下,两个数据集的记录是相同的,只是时间戳字段不同。对于我的用例,如果除时间戳字段之外的所有字段值都相同,则任何两个 Record 对象都相等。

// These two records are the same because only the timestamp differs
Record recordA = new Record(54321, 1615270861975L, "foo", "USA"); 
Record recordB = new Record(54321, 1615357219994L, "foo", "USA"); 

为了保留内存,有没有办法让两个 Record 对象“相等”,映射 A 和 B 中的这两个映射条目值将引用内存中的同一个 Record 对象?我已经覆盖了 Record 对象的 equals 和 hashCode 方法以忽略时间戳,然后检查 RecordMapA 是否已经包含相同的记录。如果是这样,我将RecordMapA中的记录放入RecordMapB中,而不是将已经从数据集B序列化的新记录放入Map B中。但是目前对内存的影响似乎可以忽略不计。

附带说明一下,我需要保留两张地图(而不是将它们合并为一张)以便以后进行比较。

如果记录是 'small enough' 那么我就不会尝试任何花哨的东西了。对于大型记录,最简单的方法似乎是做你正在做的事情。

void addToMap(Long key, Record rec, Map<Long,Record> map, 
              Map<Long,Record> otherMap) {
    Record existing = otherMap.get(key);
    map.put(key, existing != null ? existing : rec);
]

假设如果键存在则键定位的记录必须相同。如果不是这种情况,您需要检查一下。

void addToMap(Long key, Record rec, Map<Long,Record> map, 
              Map<Long,Record> otherMap) {
    Record existing = otherMap.get(key);
    if (existing != null && existing.equals(rec))
         map.put(key, existing);
    else
         map.put(key, rec);
]