@@ -125,7 +125,12 @@ public static class Builder implements org.apache.commons.text.Builder<RandomStr
125125 /**
126126 * The source of provided characters.
127127 */
128- private List <Character > characterList ;
128+ private Set <Character > characterSet = new HashSet <>();
129+
130+ /**
131+ * Whether calls accumulates the source of provided characters. The default is {@code false}.
132+ */
133+ private boolean accumulate ;
129134
130135 /**
131136 * Creates a new instance.
@@ -155,7 +160,7 @@ public RandomStringGenerator build() {
155160 * </p>
156161 *
157162 * @param predicates the predicates, may be {@code null} or empty.
158- * @return {@code this}, to allow method chaining .
163+ * @return {@code this} instance .
159164 */
160165 public Builder filteredBy (final CharacterPredicate ... predicates ) {
161166 if (ArrayUtils .isEmpty (predicates )) {
@@ -182,6 +187,12 @@ public RandomStringGenerator get() {
182187 return new RandomStringGenerator (this );
183188 }
184189
190+ private void initCharList () {
191+ if (!accumulate ) {
192+ characterSet = new HashSet <>();
193+ }
194+ }
195+
185196 /**
186197 * Limits the characters in the generated string to those who match at supplied list of Character.
187198 *
@@ -191,19 +202,43 @@ public RandomStringGenerator get() {
191202 * </p>
192203 *
193204 * @param chars set of predefined Characters for random string generation the Character can be, may be {@code null} or empty
194- * @return {@code this}, to allow method chaining .
205+ * @return {@code this} instance .
195206 * @since 1.2
196207 */
197208 public Builder selectFrom (final char ... chars ) {
198- characterList = new ArrayList <> ();
209+ initCharList ();
199210 if (chars != null ) {
200211 for (final char c : chars ) {
201- characterList .add (c );
212+ characterSet .add (c );
202213 }
203214 }
204215 return this ;
205216 }
206217
218+ /**
219+ * Sets whether calls accumulates the source of provided characters. The default is {@code false}.
220+ *
221+ * <pre>
222+ * {@code
223+ * RandomStringGenerator gen = RandomStringGenerator.builder()
224+ * .setAccumulate(true)
225+ * .withinRange(new char[][] { { 'a', 'z' }, { 'A', 'Z' }, { '0', '9' } })
226+ * .selectFrom('!', '"', '#', '$', '&', '\'', '(', ')', ',', '.', ':', ';', '?', '@', '[',
227+ * '\\', ']', '^', '_', '`', '{', '|', '}', '~') // punctuation
228+ * // additional builder calls as needed
229+ * .build();
230+ * }
231+ * </pre>
232+ *
233+ * @param accumulate whether calls accumulates the source of provided characters. The default is {@code false}.
234+ * @return {@code this} instance.
235+ * @since 1.14.0
236+ */
237+ public Builder setAccumulate (final boolean accumulate ) {
238+ this .accumulate = accumulate ;
239+ return this ;
240+ }
241+
207242 /**
208243 * Overrides the default source of randomness. It is highly recommended that a random number generator library like
209244 * <a href="https://commons.apache.org/proper/commons-rng/">Apache Commons RNG</a> be used to provide the random number generation.
@@ -227,7 +262,7 @@ public Builder selectFrom(final char... chars) {
227262 * </p>
228263 *
229264 * @param random the source of randomness, may be {@code null}.
230- * @return {@code this}, to allow method chaining .
265+ * @return {@code this} instance .
231266 * @since 1.14.0
232267 */
233268 public Builder usingRandom (final IntUnaryOperator random ) {
@@ -258,7 +293,7 @@ public Builder usingRandom(final IntUnaryOperator random) {
258293 * </p>
259294 *
260295 * @param random the source of randomness, may be {@code null}.
261- * @return {@code this}, to allow method chaining .
296+ * @return {@code this} instance .
262297 */
263298 public Builder usingRandom (final TextRandomProvider random ) {
264299 this .random = random ;
@@ -272,18 +307,17 @@ public Builder usingRandom(final TextRandomProvider random) {
272307 *
273308 * <pre>
274309 * {@code
275- *
276310 * char[][] pairs = { { '0', '9' } };
277311 * char[][] pairs = { { 'a', 'z' } };
278312 * char[][] pairs = { { 'a', 'z' }, { '0', '9' } };
279313 * }
280314 * </pre>
281315 *
282316 * @param pairs array of characters array, expected is to pass min, max pairs through this arg.
283- * @return {@code this}, to allow method chaining .
317+ * @return {@code this} instance .
284318 */
285319 public Builder withinRange (final char []... pairs ) {
286- characterList = new ArrayList <> ();
320+ initCharList ();
287321 if (pairs != null ) {
288322 for (final char [] pair : pairs ) {
289323 Validate .isTrue (pair .length == 2 , "Each pair must contain minimum and maximum code point" );
@@ -292,19 +326,20 @@ public Builder withinRange(final char[]... pairs) {
292326 Validate .isTrue (minimumCodePoint <= maximumCodePoint , "Minimum code point %d is larger than maximum code point %d" , minimumCodePoint ,
293327 maximumCodePoint );
294328 for (int index = minimumCodePoint ; index <= maximumCodePoint ; index ++) {
295- characterList .add ((char ) index );
329+ characterSet .add ((char ) index );
296330 }
297331 }
298332 }
299333 return this ;
300334 }
301335
336+
302337 /**
303338 * Sets the minimum and maximum code points allowed in the generated string.
304339 *
305340 * @param minimumCodePoint the smallest code point allowed (inclusive).
306341 * @param maximumCodePoint the largest code point allowed (inclusive).
307- * @return {@code this}, to allow method chaining .
342+ * @return {@code this} instance .
308343 * @throws IllegalArgumentException if {@code maximumCodePoint >} {@link Character#MAX_CODE_POINT}.
309344 * @throws IllegalArgumentException if {@code minimumCodePoint < 0}.
310345 * @throws IllegalArgumentException if {@code minimumCodePoint > maximumCodePoint}.
@@ -362,14 +397,14 @@ public static Builder builder() {
362397 * @param maximumCodePoint largest allowed code point (inclusive).
363398 * @param inclusivePredicates filters for code points.
364399 * @param random source of randomness.
365- * @param characterList list of predefined set of characters.
400+ * @param characterSet list of predefined set of characters.
366401 */
367402 private RandomStringGenerator (final Builder builder ) {
368403 this .minimumCodePoint = builder .minimumCodePoint ;
369404 this .maximumCodePoint = builder .maximumCodePoint ;
370405 this .inclusivePredicates = builder .inclusivePredicates ;
371406 this .random = builder .random ;
372- this .characterList = builder .characterList ;
407+ this .characterList = new ArrayList <>( builder .characterSet ) ;
373408 }
374409
375410 /**
0 commit comments