Как удалить слабую ссылку из списка?

#java #list #weak-references

#java #Список #слабые ссылки

Вопрос:

У меня есть список слабых ссылок на объекты в java. Как мне написать метод, который получает экземпляр реального объекта и удаляет его слабую ссылку из этого списка?

Спасибо.

Комментарии:

1. Вы имеете в виду метод, который принимает сильную ссылку на объект в качестве параметра?

Ответ №1:

Не совсем понятно, что вы имеете в виду, но я думаю, что вы можете захотеть:

 public static <T> void removeReference(List<WeakReference<T>> list,
                                       T reference)
{
    for (Iterator<WeakReference<T>> iterator = list.iterator();
         iterator.hasNext(); )
    {
        WeakReference<T> weakRef = iterator.next();
        if (weakRef.get() == reference)
        {
            iterator.remove();
        }
    }
}
  

Комментарии:

1. вы также могли бы удалить обнуленные слабые ссылки, пока работаете над этим

2. @ratchet: Я задавался вопросом об этом, но это зависит от того, что пытается сделать OP.

3. Как удалить нулевой элемент из списка? if (weakRef.get() == null) ?

4. @EduardoBezerra: Да, я ожидал бы, что это будет нормально.

Ответ №2:

Взгляните на Javadocs для слабой ссылки. Следует отметить две важные вещи: 1. он защищен, поэтому вы можете расширить его, и 2. он не переопределяет Object.equals()

Итак, два подхода для выполнения того, что вы хотите:

Первый, самый простой способ, используйте то, что сказал @Jon Skeet.

Второй, более элегантный способ. Примечание: это работает, только если вы единственный, кто также добавляет в список:

 public class HardReference<T> {
  private final T _object;

  public HardReference(T object) {
    assert object != null;
    _object = object;
  }

  public T get() { return _object; }

  public int hashCode() { return _object.hashCode(); }

  public boolean equals(Object other) {
    if (other instanceof HardReference) {
      return get() == ((HardReference) other).get();
    }
    if (other instanceof Reference) {
      return get() == ((Reference) other).get();
    }
    return get() == other;
  }
}

class WeakRefWithEquals<T> extends WeakReference<T> {

  WeakRefWithEquals(T object) { super(object); }

  public boolean equals(Object other) {
    if (other instanceof HardReference) {
      return get() == ((HardReference) other).get();
    }
    if (other instanceof Reference) {
      return get() == ((Reference) other).get();
    }
    return get() == other;
  }
}
  

Получив эти служебные классы, вы можете обернуть объекты, хранящиеся в списках, картах и т.д., Любым ссылочным подклассом — как в примере WeakRefWithEquals выше.
Когда вы ищете элемент, вам нужно обернуть его HardReference, на всякий случай, если реализация collection делает

 param.equals(element)
  

вместо

 element.equals(param)