1 /* 2 * Copyright the original author or authors. 3 * 4 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.mozilla.org/MPL/MPL-1.1.html 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.as2lib.data.holder.List; 18 import org.as2lib.data.holder.Iterator; 19 import org.as2lib.data.holder.array.ArrayIterator; 20 import org.as2lib.data.holder.list.AbstractList; 21 import org.as2lib.data.holder.IndexOutOfBoundsException; 22 23 /** 24 * {@code ArrayList} is a resizable-array implementation of {@code List} interface. 25 * 26 * <p>Example: 27 * <code> 28 * var list:List = new ArrayList(); 29 * list.insert("myValue1"); 30 * list.insertFirst("myValue2"); 31 * list.insertLast("myValue3"); 32 * trace(list.contains("myValue2")); 33 * trace(list.remove(0)); 34 * trace(list.contains("myValue2")); 35 * trace(list.removeLast()); 36 * trace(list.get(0)); 37 * list.clear(); 38 * trace(list.size()); 39 * </code> 40 * 41 * <p>Output: 42 * <pre> 43 * true 44 * myValue2 45 * false 46 * myValue3 47 * myValue1 48 * 0 49 * </pre> 50 * 51 * @author Simon Wacker 52 */ 53 class org.as2lib.data.holder.list.ArrayList extends AbstractList implements List { 54 55 /** Makes the static variables of the super-class accessible through this class. */ 56 private static var __proto__:Function = AbstractList; 57 58 /** Holds added values. */ 59 private var data:Array; 60 61 /** 62 * Constructs a new {@code ArrayList} instance. 63 * 64 * @param source (optional) an array that contains values to populate this new list 65 * with 66 */ 67 public function ArrayList(source:Array) { 68 if (source) { 69 data = source.concat(); 70 } else { 71 data = new Array(); 72 } 73 } 74 75 /** 76 * Inserts {@code value} at the given {@code index}. 77 * 78 * <p>The element that is currently at the given {@code index} is shifted by one to 79 * the right, as well as any subsequent elements. 80 * 81 * @param index the index at which to insert the {@code value} 82 * @param value the value to insert 83 * @throws IndexOutOfBoundsException if the given {@code index} is not in range, 84 * this is less than 0 or greater than this list's size 85 */ 86 public function insertByIndexAndValue(index:Number, value):Void { 87 if (index < 0 || index > data.length) { 88 throw new IndexOutOfBoundsException("Argument 'index' [" + index + "] is out of range, this is less than 0 or greater than this list's size [" + size() + "].", this, arguments); 89 } 90 if (index == data.length) { 91 data.push(value); 92 return; 93 } 94 if (index == 0) { 95 data.unshift(value); 96 return; 97 } 98 data.splice(index, 0, value); 99 } 100 101 /** 102 * Removes the value at given {@code index} from this list and returns it. 103 * 104 * @param index the index of the value to remove 105 * @return the removed value that was originally at given {@code index} 106 * @throws IndexOutOfBoundsException if given {@code index} is less than 0 or 107 * equal to or greater than this list's size 108 */ 109 public function removeByIndex(index:Number) { 110 if (index < 0 || index >= data.length) { 111 throw new IndexOutOfBoundsException("Argument 'index' [" + index + "] is out of range, this is less than 0 or equal to or greater than this list's size [" + size() + "].", this, arguments); 112 } 113 if (index == 0) { 114 return data.shift(); 115 } 116 if (index == data.length - 1) { 117 return data.pop(); 118 } 119 var result = data[index]; 120 data.splice(index, 1); 121 return result; 122 } 123 124 /** 125 * Sets {@code value} to given {@code index} on this list. 126 * 127 * @param index the index of {@code value} 128 * @param value the {@code value} to set to given {@code index} 129 * @return the value that was orignially at given {@code index} 130 * @throws IndexOutOfBoundsException if given {@code index} is less than 0 or 131 * equal to or greater than this list's size 132 */ 133 public function set(index:Number, value) { 134 if (index < 0 || index >= data.length) { 135 throw new IndexOutOfBoundsException("Argument 'index' [" + index + "] is out of range, this is less than 0 or equal to or greater than this list's size [" + size() + "].", this, arguments); 136 } 137 var result = data[index]; 138 data[index] = value; 139 return result; 140 } 141 142 /** 143 * Returns the value at given {@code index}. 144 * 145 * @param index the index to return the value of 146 * @return the value that is at given {@code index} 147 * @throws IndexOutOfBoundsException if given {@code index} is less than 0 or 148 * equal to or greater than this list's size 149 */ 150 public function get(index:Number) { 151 if (index < 0 || index >= data.length) { 152 throw new IndexOutOfBoundsException("Argument 'index' [" + index + "] is out of range, this is less than 0 or equal to or greater than this list's size [" + size() + "].", this, arguments); 153 } 154 return data[index]; 155 } 156 157 /** 158 * Removes all values from this list. 159 */ 160 public function clear(Void):Void { 161 data = new Array(); 162 } 163 164 /** 165 * Returns the number of added values. 166 * 167 * @return the number of added values 168 */ 169 public function size(Void):Number { 170 return data.length; 171 } 172 173 /** 174 * Returns the iterator to iterate over this list. 175 * 176 * @return the iterator to iterate over this list 177 */ 178 public function iterator(Void):Iterator { 179 return new ArrayIterator(data); 180 } 181 182 /** 183 * Returns the array representation of this list. 184 * 185 * @return the array representation of this list 186 */ 187 public function toArray(Void):Array { 188 return data.concat(); 189 } 190 191 }