001// Generated by delombok at Mon Jan 02 16:27:27 UTC 2023 002package io.cui.tools.collect; 003 004import static io.cui.tools.collect.CollectionLiterals.mutableList; 005import static java.util.Objects.requireNonNull; 006import java.lang.reflect.Array; 007import java.util.ArrayList; 008import java.util.Collection; 009import java.util.Collections; 010import java.util.Comparator; 011import java.util.HashSet; 012import java.util.Iterator; 013import java.util.List; 014import java.util.NavigableSet; 015import java.util.Optional; 016import java.util.Set; 017import java.util.TreeSet; 018import java.util.concurrent.ConcurrentSkipListSet; 019import java.util.concurrent.CopyOnWriteArrayList; 020import java.util.concurrent.CopyOnWriteArraySet; 021import java.util.stream.Stream; 022 023/** 024 * <h2>Overview</h2> 025 * Builder for creating {@link java.util.Collection}s providing some convenience methods. The class writes 026 * everything through into the contained collector. Using the default constructor a newly created 027 * {@link java.util.ArrayList} will be used as collector, but you can pass you own collector as 028 * constructor-argument. Of course this should be mutable in order to work. 029 * <h3>Handling of null-values</h3> 030 * <p> 031 * As default {@code null} values are ignored. This behavior can be changed by call 032 * {@link #addNullValues(boolean)}. 033 * <em>Caution:</em> In case of using one of the {@link #copyFrom(Collection)} 034 * methods for instantiation the {@code null} values will not be checked in that way 035 * </p> 036 * <h3>Standard Usage</h3> 037 * 038 * <pre> 039 * 040 * List<String> result = new CollectionBuilder<String>().add("this").add("that") 041 * .add(mutableList("on", "or an other")).toImmutableList(); 042 * </pre> 043 * 044 * or 045 * 046 * <pre> 047 * 048 * Set<String> result = new CollectionBuilder<String>().add("this").add("that") 049 * .add(mutableList("on", "or an other")).toMutableSet(); 050 * </pre> 051 * 052 * <h3>Copy From</h3> 053 * This methods can be used for ensuring a real copy 054 * 055 * <pre> 056 * 057 * List<String> result = 058 * CollectionBuilder.copyFrom(mutableList("on", "or an other")).add("element").toMutableList(); 059 * 060 * </pre> 061 * 062 * <h3>Sorting</h3> 063 * <p> 064 * The contained {@link java.util.Collection} can be sorted any time by calling {@link #sort(Comparator)} 065 * </p> 066 * 067 * @author Oliver Wolff 068 * @param <E> The type of the contained {@link java.util.Collection} 069 */ 070public final class CollectionBuilder<E> implements Iterable<E> { 071 private final Collection<E> collector; 072 /** 073 * If set to {@code true} {@code null} elements are added to the contained collector, if 074 * {@code false}, default value, {@code null} values are ignored. 075 */ 076 private boolean addNullValues = false; 077 078 /** 079 * <p>Constructor for CollectionBuilder.</p> 080 * 081 * @param collector to be used for storage. Must not be null 082 */ 083 public CollectionBuilder(Collection<E> collector) { 084 super(); 085 this.collector = requireNonNull(collector); 086 } 087 088 /** 089 * Default Constructor initializing the collector with an {@link java.util.ArrayList} 090 */ 091 public CollectionBuilder() { 092 this(new ArrayList<>()); 093 } 094 095 /** 096 * <p>addNullValues.</p> 097 * 098 * @param addNullValues If set to {@code true} {@code null} elements are added to the contained 099 * collector, if {@code false}, default value, {@code null} values are ignored. 100 * @return the instance itself in order to use it in a fluent way. 101 */ 102 public CollectionBuilder<E> addNullValues(boolean addNullValues) { 103 this.addNullValues = addNullValues; 104 return this; 105 } 106 107 /** 108 * <p>size.</p> 109 * 110 * @return the size of the contained Collection 111 */ 112 public int size() { 113 return collector.size(); 114 } 115 116 /** 117 * <p>isEmpty.</p> 118 * 119 * @return see {@link java.util.Collection#isEmpty()} 120 */ 121 public boolean isEmpty() { 122 return collector.isEmpty(); 123 } 124 125 /** 126 * <p>contains.</p> 127 * 128 * @param o a {@link java.lang.Object} object 129 * @return see {@link java.util.Collection#isEmpty()} 130 */ 131 public boolean contains(Object o) { 132 return collector.contains(o); 133 } 134 135 /** 136 * {@inheritDoc} 137 */ 138 @Override 139 public Iterator<E> iterator() { 140 return collector.iterator(); 141 } 142 143 /** 144 * <p>stream.</p> 145 * 146 * @return a {@link java.util.stream.Stream} on the contained objects 147 */ 148 public Stream<E> stream() { 149 return collector.stream(); 150 } 151 152 /** 153 * <p>add.</p> 154 * 155 * @param e the element to be added 156 * @return the instance itself in order to use it in a fluent way. <em>Caution:</em> with this 157 * call the return value of {@link java.util.Collection#add(Object)} will be ignored. 158 */ 159 public CollectionBuilder<E> add(E e) { 160 if (addNullValues || null != e) { 161 collector.add(e); 162 } 163 return this; 164 } 165 166 /** 167 * <p>add.</p> 168 * 169 * @param elements to be added 170 * @return the instance itself in order to use it in a fluent way. <em>Caution:</em> with this 171 * call the return value of {@link java.util.Collection#add(Object)} will be ignored. 172 */ 173 public CollectionBuilder<E> add(@SuppressWarnings("unchecked") E... elements) { 174 if (!MoreCollections.isEmpty(elements)) { 175 for (E element : elements) { 176 add(element); 177 } 178 } 179 return this; 180 } 181 182 /** 183 * <p>add.</p> 184 * 185 * @param elements to be added 186 * @return the instance itself in order to use it in a fluent way. <em>Caution:</em> with this 187 * call the return value of {@link java.util.Collection#add(Object)} will be ignored. 188 */ 189 public CollectionBuilder<E> add(Iterable<E> elements) { 190 if (!MoreCollections.isEmpty(elements)) { 191 elements.forEach(this::add); 192 } 193 return this; 194 } 195 196 /** 197 * <p>add.</p> 198 * 199 * @param elements to be added 200 * @return the instance itself in order to use it in a fluent way. <em>Caution:</em> with this 201 * call the return value of {@link java.util.Collection#add(Object)} will be ignored. 202 */ 203 public CollectionBuilder<E> add(Collection<E> elements) { 204 if (!MoreCollections.isEmpty(elements)) { 205 elements.forEach(this::add); 206 } 207 return this; 208 } 209 210 /** 211 * <p>add.</p> 212 * 213 * @param element to be added if present. 214 * <em>Caution</em>: passing an {@link java.util.Optional} 215 * parameter is a not a good thing to do, I know, but in this context it is quite 216 * convenient: Don't do this at home 217 * @return the instance itself in order to use it in a fluent way. <em>Caution:</em> with this 218 * call the return value of {@link java.util.Collection#add(Object)} will be ignored. 219 */ 220 public CollectionBuilder<E> add(Optional<E> element) { 221 element.ifPresent(this::add); 222 return this; 223 } 224 225 /** 226 * <p>add.</p> 227 * 228 * @param elements to be added 229 * @return the instance itself in order to use it in a fluent way. <em>Caution:</em> with this 230 * call the return value of {@link java.util.Collection#add(Object)} will be ignored. 231 */ 232 public CollectionBuilder<E> add(Stream<E> elements) { 233 if (!MoreCollections.isEmpty(elements)) { 234 elements.forEach(this::add); 235 } 236 return this; 237 } 238 239 /** 240 * Sorts the contained Collection. 241 * 242 * @param comparator must not be null. 243 * @return the instance itself in order to use it in a fluent way. 244 */ 245 public CollectionBuilder<E> sort(Comparator<? super E> comparator) { 246 if (collector instanceof List) { 247 Collections.sort((List<E>) collector, comparator); 248 } else { 249 List<E> sorter = new ArrayList<>(collector); 250 Collections.sort(sorter, comparator); 251 collector.clear(); 252 collector.addAll(sorter); 253 } 254 return this; 255 } 256 257 /** 258 * <p>toMutableList.</p> 259 * 260 * @return a mutable {@link java.util.List} representation of the builders content, the actual 261 * implementation is an {@link java.util.ArrayList} 262 */ 263 public List<E> toMutableList() { 264 return new ArrayList<>(collector); 265 } 266 267 /** 268 * <p>toImmutableList.</p> 269 * 270 * @return an immutable {@link java.util.List} representation of the builders content, the actual 271 * implementation calls {@link java.util.Collections#unmodifiableList(List)}. The underlying 272 * {@link java.util.Collection} will be copied by calling {@link #toMutableList()} 273 */ 274 public List<E> toImmutableList() { 275 return Collections.unmodifiableList(toMutableList()); 276 } 277 278 /** 279 * <p>toMutableSet.</p> 280 * 281 * @return a mutable {@link java.util.Set} representation of the builders content, the actual 282 * implementation is an {@link java.util.HashSet} 283 */ 284 public Set<E> toMutableSet() { 285 return new HashSet<>(collector); 286 } 287 288 /** 289 * <p>toImmutableSet.</p> 290 * 291 * @return an immutable {@link java.util.Set} representation of the builders content, the actual 292 * implementation calls {@link java.util.Collections#unmodifiableList(List)}. The underlying 293 * {@link java.util.Collection} will be copied by calling {@link #toMutableSet()} 294 */ 295 public Set<E> toImmutableSet() { 296 return Collections.unmodifiableSet(toMutableSet()); 297 } 298 299 /** 300 * <p>toConcurrentList.</p> 301 * 302 * @return a concurrent mutable {@link java.util.List} representation of the builders content, the actual 303 * implementation is an {@link java.util.concurrent.CopyOnWriteArrayList} 304 */ 305 public List<E> toConcurrentList() { 306 return new CopyOnWriteArrayList<>(collector); 307 } 308 309 /** 310 * <p>toConcurrentSet.</p> 311 * 312 * @return a concurrent mutable {@link java.util.Set} representation of the builders content, the actual 313 * implementation is an {@link java.util.concurrent.CopyOnWriteArraySet} 314 */ 315 public Set<E> toConcurrentSet() { 316 return new CopyOnWriteArraySet<>(collector); 317 } 318 319 /** 320 * <p>toMutableNavigableSet.</p> 321 * 322 * @return a mutable {@link java.util.NavigableSet} representation of the builders content, the actual 323 * implementation is an {@link java.util.TreeSet}. The assumption is that the Actual type is at 324 * least {@link java.lang.Comparable} 325 */ 326 public NavigableSet<E> toMutableNavigableSet() { 327 return new TreeSet<>(collector); 328 } 329 330 /** 331 * <p>toImmutableNavigableSet.</p> 332 * 333 * @return an immutable {@link java.util.NavigableSet} representation of the builders content, the actual 334 * implementation is an {@link java.util.TreeSet} wrapped by 335 * {@link java.util.Collections#unmodifiableNavigableSet(NavigableSet)}. The assumption is that 336 * the Actual type is at least {@link java.lang.Comparable} 337 */ 338 public NavigableSet<E> toImmutableNavigableSet() { 339 return Collections.unmodifiableNavigableSet(toMutableNavigableSet()); 340 } 341 342 /** 343 * <p>toConcurrentNavigableSet.</p> 344 * 345 * @return a mutable {@link java.util.NavigableSet} representation of the builders content, the actual 346 * implementation is an {@link java.util.concurrent.ConcurrentSkipListSet}. The assumption is that the 347 * actual type is at least {@link java.lang.Comparable} 348 */ 349 public NavigableSet<E> toConcurrentNavigableSet() { 350 return new ConcurrentSkipListSet<>(collector); 351 } 352 353 /** 354 * <p>toArray.</p> 355 * 356 * @param targetType identifying the concrete ArrayType 357 * @return an array representation of the builders content 358 */ 359 @SuppressWarnings("unchecked") 360 public E[] toArray(Class<? super E> targetType) { 361 if (isEmpty()) { 362 return (E[]) Array.newInstance(targetType, 0); 363 } 364 E[] target = (E[]) Array.newInstance(targetType, size()); 365 return collector.toArray(target); 366 } 367 368 /** 369 * Clears the elements in the collector 370 * 371 * @return the instance itself in order to use it in a fluent way. 372 */ 373 public CollectionBuilder<E> clear() { 374 collector.clear(); 375 return this; 376 } 377 378 /** 379 * Creates an Instance of {@link io.cui.tools.collect.CollectionBuilder} by copying the content of the given source 380 * <em>Caution:</em> The given source will be used as it is, there will be no filtering as 381 * defined within {@link #addNullValues(boolean)} 382 * 383 * @param source may be null 384 * @return the newly created {@link io.cui.tools.collect.CollectionBuilder} 385 * @param <E> a E class 386 */ 387 public static <E> CollectionBuilder<E> copyFrom(Iterable<? extends E> source) { 388 return new CollectionBuilder<>(mutableList(source)); 389 } 390 391 /** 392 * Creates an Instance of {@link io.cui.tools.collect.CollectionBuilder} by copying the content of the given source 393 * <em>Caution:</em> The given source will be used as it is, there will be no filtering as 394 * defined within {@link #addNullValues(boolean)} 395 * 396 * @param source may be null 397 * @return the newly created {@link io.cui.tools.collect.CollectionBuilder} 398 * @param <E> a E class 399 */ 400 public static <E> CollectionBuilder<E> copyFrom(Iterator<? extends E> source) { 401 return new CollectionBuilder<>(mutableList(source)); 402 } 403 404 /** 405 * Creates an Instance of {@link io.cui.tools.collect.CollectionBuilder} by copying the content of the given source 406 * <em>Caution:</em> The given source will be used as it is, there will be no filtering as 407 * defined within {@link #addNullValues(boolean)} 408 * 409 * @param source may be null 410 * @return the newly created {@link io.cui.tools.collect.CollectionBuilder} 411 * @param <E> a E class 412 */ 413 public static <E> CollectionBuilder<E> copyFrom(Collection<? extends E> source) { 414 return new CollectionBuilder<>(mutableList(source)); 415 } 416 417 /** 418 * Creates an Instance of {@link io.cui.tools.collect.CollectionBuilder} by copying the content of the given source 419 * <em>Caution:</em> The given source will be used as it is, there will be no filtering as 420 * defined within {@link #addNullValues(boolean)} 421 * 422 * @param source may be null 423 * @return the newly created {@link io.cui.tools.collect.CollectionBuilder} 424 * @param <E> a E class 425 */ 426 public static <E> CollectionBuilder<E> copyFrom(Stream<? extends E> source) { 427 return new CollectionBuilder<>(mutableList(source)); 428 } 429 430 /** 431 * Creates an Instance of {@link io.cui.tools.collect.CollectionBuilder} by copying the content of the given source 432 * <em>Caution:</em> The given source will be used as it is, there will be no filtering as 433 * defined within {@link #addNullValues(boolean)} 434 * 435 * @param source may be null 436 * @return the newly created {@link io.cui.tools.collect.CollectionBuilder} 437 * @param <E> a E class 438 */ 439 @SafeVarargs 440 public static <E> CollectionBuilder<E> copyFrom(E... source) { 441 return new CollectionBuilder<>(mutableList(source)); 442 } 443 444 /** 445 * Creates an Instance of {@link io.cui.tools.collect.CollectionBuilder} by copying the content of the given source 446 * <em>Caution:</em> The given source will be used as it is, there will be no filtering as 447 * defined within {@link #addNullValues(boolean)} 448 * 449 * @param source may be null 450 * @return the newly created {@link io.cui.tools.collect.CollectionBuilder} 451 * @param <E> a E class 452 */ 453 public static <E> CollectionBuilder<E> copyFrom(E source) { 454 return new CollectionBuilder<>(mutableList(source)); 455 } 456 457 @java.lang.Override 458 @java.lang.SuppressWarnings("all") 459 @lombok.Generated 460 public boolean equals(final java.lang.Object o) { 461 if (o == this) return true; 462 if (!(o instanceof CollectionBuilder)) return false; 463 final CollectionBuilder<?> other = (CollectionBuilder<?>) o; 464 if (this.isAddNullValues() != other.isAddNullValues()) return false; 465 final java.lang.Object this$collector = this.collector; 466 final java.lang.Object other$collector = other.collector; 467 if (this$collector == null ? other$collector != null : !this$collector.equals(other$collector)) return false; 468 return true; 469 } 470 471 @java.lang.Override 472 @java.lang.SuppressWarnings("all") 473 @lombok.Generated 474 public int hashCode() { 475 final int PRIME = 59; 476 int result = 1; 477 result = result * PRIME + (this.isAddNullValues() ? 79 : 97); 478 final java.lang.Object $collector = this.collector; 479 result = result * PRIME + ($collector == null ? 43 : $collector.hashCode()); 480 return result; 481 } 482 483 @java.lang.Override 484 @java.lang.SuppressWarnings("all") 485 @lombok.Generated 486 public java.lang.String toString() { 487 return "CollectionBuilder(collector=" + this.collector + ", addNullValues=" + this.isAddNullValues() + ")"; 488 } 489 490 /** 491 * If set to {@code true} {@code null} elements are added to the contained collector, if 492 * {@code false}, default value, {@code null} values are ignored. 493 */ 494 @java.lang.SuppressWarnings("all") 495 @lombok.Generated 496 public boolean isAddNullValues() { 497 return this.addNullValues; 498 } 499}