1 // Copyright (C) 2002-2003 Jon A. Maxwell (JAM) 2 // 3 // This library is free software; you can redistribute it and/or 4 // modify it under the terms of the GNU Lesser General Public 5 // License as published by the Free Software Foundation; either 6 // version 2.1 of the License, or (at your option) any later version. 7 // 8 // This library is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 // Lesser General Public License for more details. 12 // 13 // You should have received a copy of the GNU Lesser General Public 14 // License along with this library; if not, write to the Free Software 15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 17 package net.sourceforge.jnlp.util; 18 19 import java.lang.ref.*; 20 import java.util.*; 21 22 /** 23 * This list stores objects automatically using weak references. 24 * Objects are added and removed from the list as normal, but may 25 * turn to null at any point (ie, indexOf(x) followed by get(x) 26 * may return null). The weak references are only removed when 27 * the trimToSize method is called so that the indices remain 28 * constant otherwise. 29 * 30 * @author <a href="mailto:jmaxwell@users.sourceforge.net">Jon A. Maxwell (JAM)</a> - initial author 31 * @version $Revision: 1.3 $ 32 * @param <E> generic typeto be used in this list 33 */ 34 public class WeakList<E> extends AbstractList<E> { 35 36 /* list of weak references */ 37 private final ArrayList<WeakReference<E>> refs = new ArrayList<>(); 38 39 /** 40 * Create a weak random-access list. 41 */ WeakList()42 public WeakList() { 43 } 44 45 /** 46 * Extract the hard reference out of a weak reference. 47 */ deref(WeakReference<E> o)48 private E deref(WeakReference<E> o) { 49 if (o != null) 50 return o.get(); 51 else 52 return null; 53 } 54 55 /** 56 * @param index of field to get 57 * @return the object at the specified index, or null if the 58 * object has been collected. 59 */ 60 @Override get(int index)61 public E get(int index) { 62 return deref(refs.get(index)); 63 } 64 65 /** 66 * @return the size of the list, including already collected 67 * objects. 68 */ 69 @Override size()70 public int size() { 71 return refs.size(); 72 } 73 74 /** 75 * Sets the object at the specified position and returns the 76 * previous object at that position or null if it was already 77 * collected. 78 * @param index position where to place element 79 * @param element data which to put on position 80 * @return previous object on that position 81 */ 82 @Override set(int index, E element)83 public E set(int index, E element) { 84 return deref(refs.set(index, new WeakReference<>(element))); 85 } 86 87 /** 88 * Inserts the object at the specified position in the list. 89 * Automatically creates a weak reference to the object. 90 * @param index position where to insert element 91 * @param element data which to put on position 92 */ 93 @Override add(int index, E element)94 public void add(int index, E element) { 95 refs.add(index, new WeakReference<>(element)); 96 } 97 98 /** 99 * Removes the object at the specified position and returns it 100 * or returns null if it was already collected. 101 * @param index of element to be removed 102 * @return previous object on that position 103 */ 104 @Override remove(int index)105 public E remove(int index) { 106 return deref(refs.remove(index)); 107 } 108 109 /** 110 * @return a list of hard references to the objects. The 111 * returned list does not include the collected elements, so its 112 * indices do not necessarily correlate with those of this list. 113 */ hardList()114 public List<E> hardList() { 115 List<E> result = new ArrayList<>(); 116 117 for (int i = 0; i < size(); i++) { 118 E tmp = get(i); 119 120 if (tmp != null) 121 result.add(tmp); 122 } 123 124 return result; 125 } 126 127 /** 128 * Compacts the list by removing references to collected 129 * objects. 130 */ trimToSize()131 public void trimToSize() { 132 for (int i = size(); i-- > 0;) 133 if (get(i) == null) 134 remove(i); 135 } 136 137 } 138