All Downloads are FREE. Search and download functionalities are using the official Maven repository.

us.ihmc.scs2.sessionVisualizer.jfx.tools.WeakList Maven / Gradle / Ivy

package us.ihmc.scs2.sessionVisualizer.jfx.tools;

import java.lang.ref.WeakReference;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Objects;

public class WeakList extends AbstractList //implements List, RandomAccess
{
   private final ArrayList> elements;
   private ElementGarbageCollectedListener listener;

   public WeakList()
   {
      elements = new ArrayList<>();
   }

   public ElementGarbageCollectedListener setGCListener(ElementGarbageCollectedListener listener)
   {
      ElementGarbageCollectedListener oldListener = this.listener;
      this.listener = listener;
      return oldListener;
   }

   public ElementGarbageCollectedListener removeGCListener()
   {
      return setGCListener(null);
   }

   @Override
   public int size()
   {
      return elements.size();
   }

   public void cleanupReferences()
   {
      for (int i = elements.size() - 1; i >= 0; i--)
      {
         if (elements.get(i).get() == null)
         {
            removeGCedElement(i);
         }
      }
   }

   private void removeGCedElement(int i)
   {
      elements.remove(i);
      if (listener != null)
         listener.onCleanup(i);
   }

   @Override
   public E get(int index)
   {
      E element = elements.get(index).get();
      while (element == null)
      {
         removeGCedElement(index);

         if (index >= elements.size())
            return null;

         element = elements.get(index).get();
      }
      return element;
   }

   @Override
   public E set(int index, E element)
   {
      Objects.requireNonNull(element);
      WeakReference elementReplaced = elements.set(index, new WeakReference<>(element));
      return elementReplaced == null ? null : elementReplaced.get();
   }

   @Override
   public void add(int index, E element)
   {
      Objects.requireNonNull(element);
      elements.add(index, new WeakReference<>(element));
   }

   @Override
   public E remove(int index)
   {
      WeakReference elementRemoved = elements.remove(index);
      return elementRemoved == null ? null : elementRemoved.get();
   }

   @Override
   public int indexOf(Object query)
   {
      Objects.requireNonNull(query);
      for (int i = 0; i < elements.size(); )
      {
         E candidate = elements.get(i).get();

         if (candidate == null)
            removeGCedElement(i);
         else if (query.equals(candidate))
            return i;
         else
            i++;
      }
      return -1;
   }

   @Override
   public int lastIndexOf(Object query)
   {
      Objects.requireNonNull(query);
      cleanupReferences();
      for (int i = elements.size() - 1; i >= 0; i--)
      {
         E candidate = elements.get(i).get();

         if (candidate == null)
            removeGCedElement(i);
         else if (query.equals(candidate))
            return i;
      }
      return -1;
   }

   @Override
   public void clear()
   {
      elements.clear();
   }

   @Override
   public boolean equals(Object o)
   {
      cleanupReferences();
      return super.equals(o);
   }

   @Override
   public int hashCode()
   {
      int hashCode = 1;
      for (int i = 0; i < size(); i++)
      {
         E e = get(i);
         hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
      }
      return hashCode;
   }

   public interface ElementGarbageCollectedListener
   {
      void onCleanup(int itemCollectedIndex);
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy