Java tutorial
/** * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.leo.list; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import org.apache.commons.collections4.list.TreeList; /** * CombinedList * <pre> * Internaly combine implementations of ArrayList, HashSet and TreeList * <pre> * @author Leo Lewis */ public class CombinedList<E> extends AbstractList<E> { /** Serial version UID */ private static final long serialVersionUID = -1801575433602378342L; /** HashSet */ private HashSet<E> hashSet; /** ArrayList */ private ArrayList<E> arrayList; /** TreeList */ private TreeList<E> treeList; /** If hashSet is up-to-date */ private boolean isHashSetUpToDate = true; /** If arrayList is up-to-date */ private boolean isArrayListUpToDate = true; /** If treeList is up-to-date */ private boolean isTreeListUpToDate = true; /** * Constructor */ public CombinedList() { super(); init(); } /** * Constructor * * @param c */ public CombinedList(Collection<? extends E> c) { this(); addAll(c); } /** * Initialize custom structures */ private void init() { hashSet = new HashSet<E>(); arrayList = new ArrayList<E>(); treeList = new TreeList<E>(); } /** * Update the arrayList if out of date */ private void updateArrayListIfOutOfDate() { // TreeList is necessarily up-to-date if (!isArrayListUpToDate) { arrayList.clear(); arrayList.addAll(treeList); isArrayListUpToDate = true; } } /** * Update the treeList if out of date */ private void updateTreeListIfOutOfDate() { // arrayList is necessarily up-to-date if (!isTreeListUpToDate) { treeList.clear(); treeList.addAll(arrayList); isTreeListUpToDate = true; } } /** * Update the hashSet if out of date */ private void updateHashSetIfOutOfDate() { // one of the two collection arrayList or TreeList is necessarily // up-to-date if (!isHashSetUpToDate) { hashSet.clear(); if (isArrayListUpToDate) { hashSet.addAll(arrayList); } else { hashSet.addAll(treeList); } isHashSetUpToDate = true; } } /** * Set collection other than ArrayList out-of-date */ private void setOtherThanArrayListOutOfDate() { isHashSetUpToDate = false; isTreeListUpToDate = false; } /** * Set collection other than TreeList out-of-date */ private void setOtherThanTreeListOutOfDate() { isHashSetUpToDate = false; isArrayListUpToDate = false; } /** * @see java.util.Collection#contains(java.lang.Object) */ @Override public boolean contains(Object o) { // most efficient is HashSet updateHashSetIfOutOfDate(); return hashSet.contains(o); } /** * @see java.util.Collection#containsAll(java.util.Collection) */ @Override public boolean containsAll(Collection<?> c) { // most efficient is HashSet updateHashSetIfOutOfDate(); return hashSet.containsAll(c); } /** * @see java.util.List#indexOf(java.lang.Object) */ @Override public int indexOf(Object o) { // most efficient is ArrayList updateArrayListIfOutOfDate(); return arrayList.indexOf(o); } /** * @see java.util.List#lastIndexOf(java.lang.Object) */ @Override public int lastIndexOf(Object o) { // most efficient is ArrayList updateArrayListIfOutOfDate(); return arrayList.lastIndexOf(o); } /** * @see java.util.List#get(int) */ @Override public E get(int index) { // most efficient is ArrayList updateArrayListIfOutOfDate(); return arrayList.get(index); } /** * @see java.util.List#set(int, java.lang.Object) */ @Override public E set(int index, E element) { modCount++; // most efficient is ArrayList updateArrayListIfOutOfDate(); E old = arrayList.set(index, element); setOtherThanArrayListOutOfDate(); return old; } /** * @see java.util.Collection#add(java.lang.Object) */ @Override public boolean add(E element) { modCount++; // most efficient is ArrayList updateArrayListIfOutOfDate(); boolean added = arrayList.add(element); if (added) { setOtherThanArrayListOutOfDate(); } return added; } /** * @see java.util.List#add(int, java.lang.Object) */ @Override public void add(int index, E element) { modCount++; // most efficient is TreeList updateTreeListIfOutOfDate(); treeList.add(index, element); setOtherThanTreeListOutOfDate(); } /** * @see java.util.Collection#addAll(java.util.Collection) */ @Override public boolean addAll(Collection<? extends E> col) { modCount++; // most efficient is ArrayList updateArrayListIfOutOfDate(); boolean addedAll = arrayList.addAll(col); if (addedAll) { setOtherThanArrayListOutOfDate(); } return addedAll; } /** * @see java.util.List#addAll(int, java.util.Collection) */ @Override public boolean addAll(int index, Collection<? extends E> col) { modCount++; // most efficient is TreeList updateTreeListIfOutOfDate(); boolean addedAll = treeList.addAll(index, col); if (addedAll) { setOtherThanTreeListOutOfDate(); } return addedAll; } /** * @see java.util.List#remove(int) */ @Override public E remove(int index) { modCount++; // most efficient is TreeList updateTreeListIfOutOfDate(); E removed = (E) treeList.remove(index); if (removed != null) { setOtherThanTreeListOutOfDate(); } return removed; } /** * @see java.util.Collection#remove(java.lang.Object) */ @Override public boolean remove(Object o) { modCount++; // most efficient is TreeList updateTreeListIfOutOfDate(); boolean removed = treeList.remove(o); if (removed) { setOtherThanTreeListOutOfDate(); } return removed; } /** * @see java.util.Collection#removeAll(java.util.Collection) */ @Override public boolean removeAll(Collection<?> col) { modCount++; // most efficient is TreeList updateTreeListIfOutOfDate(); boolean removedAll = treeList.removeAll(col); if (removedAll) { setOtherThanTreeListOutOfDate(); } return removedAll; } /** * @see java.util.Collection#retainAll(java.util.Collection) */ @Override public boolean retainAll(Collection<?> col) { modCount++; // most efficient is TreeList updateTreeListIfOutOfDate(); // performances issues on the retainAll method boolean retainedAll = treeList.removeAll(new HashSet<>(col)); if (retainedAll) { setOtherThanTreeListOutOfDate(); } return retainedAll; } /** * @see java.util.List#subList(int, int) */ @Override public List<E> subList(int fromIndex, int toIndex) { // most efficient is TreeList updateTreeListIfOutOfDate(); return treeList.subList(fromIndex, toIndex); } /** * @see java.util.Collection#toArray() */ @Override public Object[] toArray() { // most efficient is ArrayList updateArrayListIfOutOfDate(); return arrayList.toArray(); } /** * @see java.util.Collection#toArray(T[]) */ @Override public <T> T[] toArray(T[] a) { // most efficient is ArrayList updateArrayListIfOutOfDate(); return arrayList.toArray(a); } /** * @see java.util.Collection#size() */ @Override public int size() { if (isArrayListUpToDate) { return arrayList.size(); } else { return treeList.size(); } } /** * @see java.util.Collection#isEmpty() */ @Override public boolean isEmpty() { if (isArrayListUpToDate) { return arrayList.isEmpty(); } else { return treeList.isEmpty(); } } /** * @see java.util.Collection#clear() */ @Override public void clear() { modCount++; hashSet.clear(); arrayList.clear(); treeList.clear(); isHashSetUpToDate = true; isArrayListUpToDate = true; isTreeListUpToDate = true; } /** * @see java.lang.Object#clone() */ @Override public Object clone() { return new CombinedList<E>(this); } /** * @see java.lang.Object#toString() */ @Override public String toString() { if (isArrayListUpToDate) { return arrayList.toString(); } else { return treeList.toString(); } } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (isArrayListUpToDate) { return arrayList.equals(obj); } else { return treeList.equals(obj); } } }