Java: пул объектов и наборы хэшей - PullRequest
0 голосов
/ 12 мая 2019

давайте предположим, что следующий класс ...

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 и утилизации?

1 Ответ

2 голосов
/ 13 мая 2019

Что случилось с этими "дублирующими" экземплярами? Они "утеряны" и мусор собран?

Да, они будут иметь право на GC сразу после завершения текущей итерации while (there-is-data)

Если бы я хотел сохранить эти экземпляры доступными в пуле, какой был бы наиболее эффективный способ проверки на наличие дубликатов перед вставкой с использованием экземпляров addAll и утилизации?

Set.add возвращает true, если элемент вставлен, и false, если он повторяется. Таким образом, вы можете заменить addAll на

for (Foo f : buffer) {
  if (!foos.add(f)) {
    // handle duplicate
  }
}

Не будет никакого снижения производительности, потому что addAll делает то же самое - повторяет и добавляет один за другим.

...