001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.collections; 014 015import static java.util.Collections.*; 016 017import java.lang.reflect.*; 018import java.util.*; 019 020import org.apache.juneau.internal.*; 021import org.apache.juneau.json.*; 022import org.apache.juneau.serializer.*; 023 024/** 025 * A fluent {@link ArrayList}. 026 * 027 * <p> 028 * Provides various convenience methods for creating and populating a list with minimal code. 029 * 030 * <h5 class='figure'>Examples:</h5> 031 * <p class='bcode w800'> 032 * <jc>// A list of strings.</jc> 033 * AList<String> l = AList.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>); 034 * 035 * <jc>// Append to list.</jc> 036 * l.a(<js>"baz"</js>).a(<js>"qux"</js>); 037 * 038 * <jc>// Create an unmodifiable view of this list.</jc> 039 * List<String> l2 = l.unmodifiable(); 040 * 041 * <jc>// Convert it to an array.</jc> 042 * String[] array = l.asArrayOf(String.<jk>class</jk>); 043 * 044 * <jc>// Convert to simplified JSON.</jc> 045 * String json = l.asString(); 046 * 047 * <jc>// Convert to XML.</jc> 048 * String json = l.asString(XmlSerializer.<jsf>DEFAULT</jsm>); 049 * </p> 050 * 051 * @param <T> The entry type. 052 */ 053@SuppressWarnings({"unchecked"}) 054public final class AList<T> extends ArrayList<T> { 055 056 private static final long serialVersionUID = 1L; 057 058 //------------------------------------------------------------------------------------------------------------------ 059 // Constructors. 060 //------------------------------------------------------------------------------------------------------------------ 061 062 /** 063 * Constructor. 064 * 065 * <p> 066 * Creates an array list of default size. 067 */ 068 public AList() {} 069 070 /** 071 * Constructor. 072 * 073 * <p> 074 * Creates an array list of default size. 075 * @param capacity Initial capacity. 076 */ 077 public AList(int capacity) { 078 super(capacity); 079 } 080 081 /** 082 * Copy constructor. 083 * 084 * @param c Initial contents. Can be <jk>null</jk>. 085 */ 086 public AList(Collection<T> c) { 087 super(c == null ? emptyList() : c); 088 } 089 090 //------------------------------------------------------------------------------------------------------------------ 091 // Creators. 092 //------------------------------------------------------------------------------------------------------------------ 093 094 /** 095 * Convenience method for creating an empty list of objects. 096 * 097 * <p> 098 * Creates an array list of default size. 099 * 100 * @return A new list. 101 */ 102 public static <T> AList<T> of() { 103 return new AList<>(); 104 } 105 106 /** 107 * Convenience method for creating a list of objects. 108 * 109 * @param t The initial values. 110 * @return A new list. 111 */ 112 @SafeVarargs 113 public static <T> AList<T> of(T...t) { 114 return new AList<T>(t.length).a(t); 115 } 116 117 /** 118 * Convenience method for creating a list of objects. 119 * 120 * <p> 121 * Identical to {@link #of(Object...)} but allows you to distinguish from {@link #of(Collection)} when creating 122 * multi-dimensional lists. 123 * 124 * @param t The initial values. 125 * @return A new list. 126 */ 127 public static <T> AList<T> ofa(T...t) { 128 return new AList<T>(t.length).a(t); 129 } 130 131 /** 132 * Convenience method for creating a list of objects. 133 * 134 * <p> 135 * Creates a list with the same capacity as the array. 136 * 137 * @param c The initial values. 138 * @return A new list. 139 */ 140 public static <T> AList<T> of(Collection<T> c) { 141 c = c == null ? emptyList() : c; 142 return new AList<T>(c.size()).aa(c); 143 } 144 145 /** 146 * Creates a copy of the collection if it's not <jk>null</jk>. 147 * 148 * @param c The initial values. 149 * @return A new list, or <jk>null</jk> if the collection is <jk>null</jk>. 150 */ 151 public static <T> AList<T> nullable(Collection<T> c) { 152 return c == null ? null : of(c); 153 } 154 155 /** 156 * Convenience method for creating an unmodifiable list of objects. 157 * 158 * <p> 159 * Creates a list with the same capacity as the array. 160 * 161 * @param t The initial values. 162 * @return A new list. 163 */ 164 public static <T> List<T> unmodifiable(T...t) { 165 return t.length == 0 ? emptyList() : of(t).unmodifiable(); 166 } 167 168 /** 169 * Convenience method for creating an unmodifiable list out of the specified collection. 170 * 171 * @param c The collection to add. 172 * @param <T> The element type. 173 * @return An unmodifiable list, never <jk>null</jk>. 174 */ 175 public static <T> List<T> unmodifiable(Collection<T> c) { 176 if (c == null || c.isEmpty()) 177 return Collections.emptyList(); 178 return new AList<T>(c.size()).aa(c).unmodifiable(); 179 } 180 181 //------------------------------------------------------------------------------------------------------------------ 182 // Appenders. 183 //------------------------------------------------------------------------------------------------------------------ 184 185 /** 186 * Add. 187 * 188 * <p> 189 * Adds an entry to this list. 190 * 191 * @param t The entry to add to this list. 192 * @return This object (for method chaining). 193 */ 194 public AList<T> a(T t) { 195 add(t); 196 return this; 197 } 198 199 /** 200 * Add. 201 * 202 * <p> 203 * Adds multiple entries to this list. 204 * 205 * @param t The entries to add to this list. 206 * @return This object (for method chaining). 207 */ 208 public AList<T> a(T...t) { 209 Collections.addAll(this, t); 210 return this; 211 } 212 213 /** 214 * Add all. 215 * 216 * <p> 217 * Adds all the entries in the specified collection to this list. 218 * 219 * @param c The collection to add to this list. Can be <jk>null</jk>. 220 * @return This object (for method chaining). 221 */ 222 public AList<T> aa(Collection<? extends T> c) { 223 if (c != null) 224 addAll(c); 225 return this; 226 } 227 228 /** 229 * Add if. 230 * 231 * <p> 232 * Adds an entry to this list if the boolean flag is <jk>true</jk>. 233 * 234 * @param b The boolean flag. 235 * @param val The value to add. 236 * @return This object (for method chaining). 237 */ 238 public AList<T> aif(boolean b, T val) { 239 if (b) 240 a(val); 241 return this; 242 } 243 244 /** 245 * Add if not null. 246 * 247 * <p> 248 * Adds entries to this list skipping <jk>null</jk> values. 249 * 250 * @param t The objects to add to the list. 251 * @return This object (for method chaining). 252 */ 253 public AList<T> aifnn(T...t) { 254 for (T o2 : t) 255 if (o2 != null) 256 a(o2); 257 return this; 258 } 259 260 /** 261 * Add reverse. 262 * 263 * <p> 264 * Adds all the entries in the specified collection to this list in reverse order. 265 * 266 * @param c The collection to add to this list. 267 * @return This object (for method chaining). 268 */ 269 public AList<T> arev(List<? extends T> c) { 270 for (ListIterator<? extends T> i = c.listIterator(c.size()); i.hasPrevious();) 271 add(i.previous()); 272 return this; 273 } 274 275 /** 276 * Add reverse. 277 * 278 * <p> 279 * Adds the contents of the array to the list in reverse order. 280 * 281 * <p> 282 * i.e. add values from the array from end-to-start order to the end of the list. 283 * 284 * @param c The collection to add to this list. 285 * @return This object (for method chaining). 286 */ 287 public AList<T> arev(T[] c) { 288 for (int i = c.length - 1; i >= 0; i--) 289 add(c[i]); 290 return this; 291 } 292 293 //------------------------------------------------------------------------------------------------------------------ 294 // Other methods. 295 //------------------------------------------------------------------------------------------------------------------ 296 297 /** 298 * Returns an unmodifiable view of this list. 299 * 300 * @return An unmodifiable view of this list. 301 */ 302 public List<T> unmodifiable() { 303 return isEmpty() ? emptyList() : unmodifiableList(this); 304 } 305 306 /** 307 * Convert the contents of this list into a new array. 308 * 309 * @param c The component type of the array. 310 * @return A new array. 311 */ 312 public <T2> T2[] asArrayOf(Class<T2> c) { 313 return toArray((T2[])Array.newInstance(c, size())); 314 } 315 316 /** 317 * Returns a reverse iterable over this list. 318 * 319 * @return An iterable over the collection. 320 */ 321 public Iterable<T> riterable() { 322 return new ReverseIterable<>(this); 323 } 324 325 /** 326 * Convert to a string using the specified serializer. 327 * 328 * @param ws The serializer to use to serialize this collection. 329 * @return This collection serialized to a string. 330 */ 331 public String asString(WriterSerializer ws) { 332 return ws.toString(this); 333 } 334 335 /** 336 * Convert to Simplified JSON. 337 * 338 * @return This collection serialized to a string. 339 */ 340 public String asString() { 341 return SimpleJsonSerializer.DEFAULT.toString(this); 342 } 343 344 /** 345 * Convert to Simplified JSON. 346 */ 347 @Override /* Object */ 348 public String toString() { 349 return asString(SimpleJsonSerializer.DEFAULT); 350 } 351}