#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)