001/* Copyright (C) 2013 TU Dortmund 002 * This file is part of AutomataLib, http://www.automatalib.net/. 003 * 004 * AutomataLib is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU Lesser General Public 006 * License version 3.0 as published by the Free Software Foundation. 007 * 008 * AutomataLib is distributed in the hope that it will be useful, 009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 011 * Lesser General Public License for more details. 012 * 013 * You should have received a copy of the GNU Lesser General Public 014 * License along with AutomataLib; if not, see 015 * http://www.gnu.de/documents/lgpl.en.html. 016 */ 017package net.automatalib.commons.smartcollections; 018 019import java.util.AbstractCollection; 020import java.util.Collection; 021import java.util.Iterator; 022import java.util.Objects; 023 024 025/** 026 * This class eases the implementation of the {@link SmartCollection} 027 * interface. It is comparable to {@link AbstractCollection} from the 028 * Java Collections Framework. 029 * 030 * A class extending this abstract class has to implement the following 031 * methods: 032 * - {@link Collection#size()} 033 * - {@link SmartCollection#get(ElementReference)} 034 * - {@link SmartCollection#referenceIterator()} 035 * - {@link SmartCollection#referencedAdd(Object)} 036 * - {@link SmartCollection#remove(ElementReference)} 037 * - {@link SmartCollection#replace(ElementReference, Object)} 038 * 039 * @author Malte Isberner <malte.isberner@gmail.com> 040 * 041 * @param <E> element class. 042 */ 043public abstract class AbstractSmartCollection<E> extends AbstractCollection<E> implements SmartCollection<E> { 044 045 /* 046 * An iterator for iterating over the concrete elements, based on the 047 * iteration over the element references. 048 */ 049 private class DeRefIterator implements Iterator<E> { 050 // the reference iterator 051 private Iterator<ElementReference> refIterator; 052 053 /** 054 * Constructor. 055 * @param refIterator the reference iterator. 056 */ 057 public DeRefIterator(Iterator<ElementReference> refIterator) { 058 this.refIterator = refIterator; 059 } 060 061 /* 062 * (non-Javadoc) 063 * @see java.util.Iterator#hasNext() 064 */ 065 @Override 066 public boolean hasNext() { 067 return refIterator.hasNext(); 068 } 069 070 /* 071 * (non-Javadoc) 072 * @see java.util.Iterator#next() 073 */ 074 @Override 075 public E next() { 076 return get(refIterator.next()); 077 } 078 079 /* 080 * (non-Javadoc) 081 * @see java.util.Iterator#remove() 082 */ 083 @Override 084 public void remove() { 085 refIterator.remove(); 086 } 087 } 088 089 /* 090 * (non-Javadoc) 091 * @see de.ls5.collections.SmartCollection#addAll(java.lang.Iterable) 092 */ 093 @Override 094 public void addAll(Iterable<? extends E> iterable) { 095 for(E e : iterable) 096 add(e); 097 } 098 099 /* 100 * (non-Javadoc) 101 * @see de.ls5.collections.SmartCollection#addAll(T[]) 102 */ 103 @Override 104 public <T extends E> void addAll(T[] array) { 105 for(T t : array) 106 add(t); 107 } 108 109 /* 110 * (non-Javadoc) 111 * @see de.ls5.collections.SmartCollection#choose() 112 */ 113 @Override 114 public E choose() { 115 return iterator().next(); 116 } 117 118 /* 119 * (non-Javadoc) 120 * @see de.ls5.collections.SmartCollection#chooseRef() 121 */ 122 @Override 123 public ElementReference chooseRef() { 124 return referenceIterator().next(); 125 } 126 127 128 /* 129 * (non-Javadoc) 130 * @see java.util.AbstractCollection#add(java.lang.Object) 131 */ 132 @Override 133 public boolean add(E e) { 134 referencedAdd(e); 135 return true; 136 } 137 138 139 /* 140 * (non-Javadoc) 141 * @see de.ls5.collections.SmartCollection#references() 142 */ 143 @Override 144 public Iterable<ElementReference> references() { 145 return new Iterable<ElementReference>() { 146 @Override 147 public Iterator<ElementReference> iterator() { 148 return referenceIterator(); 149 } 150 }; 151 } 152 153 /* 154 * (non-Javadoc) 155 * @see java.util.AbstractCollection#iterator() 156 */ 157 @Override 158 public Iterator<E> iterator() { 159 return new DeRefIterator(referenceIterator()); 160 } 161 162 /* 163 * (non-Javadoc) 164 * @see de.ls5.collections.SmartCollection#find(java.lang.Object) 165 */ 166 @Override 167 public ElementReference find(Object element) { 168 for(ElementReference ref : references()) { 169 E current = get(ref); 170 if(Objects.equals(current, element)) 171 return ref; 172 } 173 174 return null; 175 } 176 177 178 /* 179 * (non-Javadoc) 180 * @see java.util.AbstractCollection#remove(java.lang.Object) 181 */ 182 @Override 183 public boolean remove(Object element) { 184 ElementReference ref = find(element); 185 if(ref == null) 186 return false; 187 remove(ref); 188 return true; 189 } 190 191 /* 192 * (non-Javadoc) 193 * @see de.ls5.smartcollections.SmartCollection#deepClear() 194 */ 195 @Override 196 public void deepClear() { 197 clear(); 198 } 199 200 /* 201 * (non-Javadoc) 202 * @see de.ls5.smartcollections.SmartCollection#quickClear() 203 */ 204 @Override 205 public void quickClear() { 206 clear(); 207 } 208 209 210}