LinkedIdentityHashSet

Я знаю как IdentityHashSet (через Collections#newSetFromMap(Map)) и LinkedHashSet. Однако мне нужна комбинация из двух, a LinkedIdentityHashSet. Я не мог найти готовое решение в сети. Кто-нибудь знает, как настроить это?

Спасибо за совет!

Ответ 1

Методы внедрения там не выходят замуж очень хорошо. LinkedHashMap добавляет связанный список к объектам записи карты. IdentityHashMap использует метод зондирования и поэтому избегает наличия каких-либо объектов ввода.

Есть несколько способов добавить характеристики "identity" к коллекции/карте.

  • Заставьте тип ключа правильно вести себя с помощью методов final equals и hashCode. На самом деле все типы ссылочных типов должны иметь это, но неважно.
  • Если вы не можете изменить equals и hashCode, но можете изменить класс, добавьте поле final, имеющее класс final, содержащий final ссылки на тип, который вы собираетесь использовать в качестве ключа. Используйте новое поле в качестве ключа.
  • Сохраните объекты адаптера в коллекции/карте. Вам понадобится создать новый экземпляр адаптера для каждого поиска. Он просто имеет методы equals/hashCode для вызова ==/System.identityHashCode исходного объекта.

Ответ 2

Один из вариантов - использовать LinkedHashSet и обертку

class LinkedIdentityHashSet<E> extends AbstractSet<E> {
    Set set = new LinkedHashSet();

    static class IdentityWrapper {
        Object obj;

        IdentityWrapper(Object obj) {
            this.obj = obj;
        }

        public boolean equals(Object obj) {
            return this.obj == obj;
        }

        public int hashCode() {
            return System.identityHashCode(obj);
        }
    }

    public boolean add(E e) {
        return set.add(new IdentityWrapper(e));
    }
...

Ответ 3

Вы можете реализовать настраиваемую карту, которая использует объекты Wrapper, которые используют семантику идентификации, и использовать встроенный LinkedHashSet, который использует эти объекты Wrapper.