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.internal; 014 015import static org.apache.juneau.internal.ConsumerUtils.*; 016 017import java.lang.reflect.*; 018import java.util.*; 019import java.util.function.*; 020 021/** 022 * Builder for arrays. 023 * 024 * <p> 025 * Designed to create arrays without array copying. 026 * Initial capacity cannot be exceeded without throwing a {@link ArrayIndexOutOfBoundsException}. 027 * 028 * <h5 class='section'>See Also:</h5><ul> 029 * </ul> 030 * 031 * @param <E> The array element type. 032 */ 033public final class ArrayBuilder<E> { 034 035 //----------------------------------------------------------------------------------------------------------------- 036 // Static 037 //----------------------------------------------------------------------------------------------------------------- 038 039 /** 040 * Static creator. 041 * 042 * @param <E> The element type. 043 * @param elementType The element type. 044 * @return A new builder object. 045 */ 046 public static <E> ArrayBuilder<E> of(Class<E> elementType) { 047 return new ArrayBuilder<>(elementType); 048 } 049 050 //----------------------------------------------------------------------------------------------------------------- 051 // Instance 052 //----------------------------------------------------------------------------------------------------------------- 053 054 private Predicate<E> filter; 055 private final Class<E> elementType; 056 private int size = -1; 057 private int i = 0; 058 private List<E> list; 059 060 /** 061 * Constructor. 062 * 063 * @param elementType The element type. 064 */ 065 public ArrayBuilder(Class<E> elementType) { 066 this.elementType = elementType; 067 } 068 069 /** 070 * Sets the expected size for this array. 071 * 072 * @param value The new value for this setting. 073 * @return This object. 074 */ 075 public ArrayBuilder<E> size(int value) { 076 size = value; 077 return this; 078 } 079 080 /** 081 * The predicate to use to filter values added to this builder. 082 * 083 * @param value The new value for this setting. 084 * @return This object. 085 */ 086 public ArrayBuilder<E> filter(Predicate<E> value) { 087 filter = value; 088 return this; 089 } 090 091 /** 092 * Appends to this array if the specified value is not null. 093 * 094 * @param t The element to add. 095 * @return This object. 096 * @throws ArrayIndexOutOfBoundsException if size is exceeded. 097 */ 098 public ArrayBuilder<E> add(E t) { 099 if (test(filter, t)) { 100 if (list == null) 101 list = size < 0 ? new ArrayList<>() : new ArrayList<>(size); 102 list.add(t); 103 i++; 104 } 105 return this; 106 } 107 108 /** 109 * Returns the populated array. 110 * 111 * @param def The default value if no values were added to this builder. 112 * @return A new array containing the added entries. 113 */ 114 @SuppressWarnings("unchecked") 115 public E[] orElse(E[] def) { 116 if (list == null) 117 return def; 118 E[] t = (E[]) Array.newInstance(elementType, list == null ? 0 : list.size()); 119 if (list != null) 120 list.toArray(t); 121 return t; 122 } 123}