001 /*--------------------------------------------------------------------------+
002 $Id: PairList.java 28497 2010-06-22 09:27:40Z deissenb $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.collections;
019
020 import java.util.ArrayList;
021 import java.util.List;
022
023 import edu.tum.cs.commons.assertion.CCSMPre;
024
025 /**
026 * A list for storing pairs in a specific order.
027 *
028 * @author hummelb
029 * @author $Author: deissenb $
030 * @version $Rev: 28497 $
031 * @levd.rating GREEN Hash: 5510B017A5CFB62174A38A897F2160AD
032 */
033 public class PairList<S, T> {
034
035 /** The current size. */
036 private int size = 0;
037
038 /** The array used for storing the S. */
039 private Object[] firstElements;
040
041 /** The array used for storing the T. */
042 private Object[] secondElements;
043
044 /** Constructor. */
045 public PairList() {
046 this(16);
047 }
048
049 /** Constructor. */
050 public PairList(int initialCapacity) {
051 firstElements = new Object[initialCapacity];
052 secondElements = new Object[initialCapacity];
053 }
054
055 /** Copy constructor. */
056 public PairList(PairList<S, T> other) {
057 this(other.size);
058 addAll(other);
059 }
060
061 /** Returns whether the list is empty. */
062 public boolean isEmpty() {
063 return size == 0;
064 }
065
066 /** Returns the size of the list. */
067 public int size() {
068 return size;
069 }
070
071 /** Add the given pair to the list. */
072 public void add(S first, T second) {
073 ensureSpace(size + 1);
074 firstElements[size] = first;
075 secondElements[size] = second;
076 ++size;
077 }
078
079 /** Adds all pairs from another list. */
080 public void addAll(PairList<S, T> other) {
081 // we have to store this in a local var, as other.size may change if
082 // other == this
083 int otherSize = other.size;
084
085 ensureSpace(size + otherSize);
086 for (int i = 0; i < otherSize; ++i) {
087 firstElements[size] = other.firstElements[i];
088 secondElements[size] = other.secondElements[i];
089 ++size;
090 }
091 }
092
093 /** Make sure there is space for at least the given amount of elements. */
094 protected void ensureSpace(int space) {
095 if (space <= firstElements.length) {
096 return;
097 }
098
099 Object[] oldFirst = firstElements;
100 Object[] oldSecond = secondElements;
101 int newSize = firstElements.length * 2;
102 while (newSize < space) {
103 newSize *= 2;
104 }
105
106 firstElements = new Object[newSize];
107 secondElements = new Object[newSize];
108 System.arraycopy(oldFirst, 0, firstElements, 0, size);
109 System.arraycopy(oldSecond, 0, secondElements, 0, size);
110 }
111
112 /** Returns the first element at given index. */
113 @SuppressWarnings("unchecked")
114 public S getFirst(int i) {
115 checkWithinBounds(i);
116 return (S) firstElements[i];
117 }
118
119 /**
120 * Checks whether the given <code>i</code> is within the bounds. Throws an
121 * exception otherwise.
122 */
123 private void checkWithinBounds(int i) {
124 if (i < 0 || i >= size) {
125 throw new IndexOutOfBoundsException("Out of bounds: " + i);
126 }
127 }
128
129 /** Sets the first element at given index. */
130 public void setFirst(int i, S value) {
131 checkWithinBounds(i);
132 firstElements[i] = value;
133 }
134
135 /** Returns the second element at given index. */
136 @SuppressWarnings("unchecked")
137 public T getSecond(int i) {
138 checkWithinBounds(i);
139 return (T) secondElements[i];
140 }
141
142 /** Sets the first element at given index. */
143 public void setSecond(int i, T value) {
144 checkWithinBounds(i);
145 secondElements[i] = value;
146 }
147
148 /** Creates a new list containing all first elements. */
149 @SuppressWarnings("unchecked")
150 public List<S> extractFirstList() {
151 List<S> result = new ArrayList<S>(size + 1);
152 for (int i = 0; i < size; ++i) {
153 result.add((S) firstElements[i]);
154 }
155 return result;
156 }
157
158 /** Creates a new list containing all second elements. */
159 @SuppressWarnings("unchecked")
160 public List<T> extractSecondList() {
161 List<T> result = new ArrayList<T>(size + 1);
162 for (int i = 0; i < size; ++i) {
163 result.add((T) secondElements[i]);
164 }
165 return result;
166 }
167
168 /**
169 * Swaps the pairs of this list. Is S and T are different types, this will
170 * be extremely dangerous.
171 */
172 public void swapPairs() {
173 Object[] temp = firstElements;
174 firstElements = secondElements;
175 secondElements = temp;
176 }
177
178 /** Clears this list. */
179 public void clear() {
180 size = 0;
181 }
182
183 /** Removes the last element of the list. */
184 public void removeLast() {
185 CCSMPre.isTrue(size > 0, "Size must be positive!");
186 size -= 1;
187 }
188 }