Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/java.base/share/classes/java/util/StringJoiner.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,36 @@ public StringJoiner(CharSequence delimiter,
checkAddLength(0, 0);
}

/**
* Constructs a {@code StringJoiner} with no characters in it using copies
* of the supplied {@code prefix}, {@code delimiter} and {@code suffix}.
* If no characters are added to the {@code StringJoiner} and methods
* accessing the string value of it are invoked, it will return the
* {@code prefix + suffix} (or properties thereof) in the result, unless
* {@code setEmptyValue} has first been called.
*
* @param delimiter the sequence of characters to be used between each
* element added to the {@code StringJoiner}
* @param prefix the sequence of characters to be used at the beginning
* @param suffix the sequence of characters to be used at the end
* @param initialCapacity the number of elements that can be added before
* the internal buffer needs to be resized
* @throws NullPointerException if {@code prefix}, {@code delimiter}, or
* {@code suffix} is {@code null}
*/
public StringJoiner(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix,
int initialCapacity) {
this(delimiter, prefix, suffix);
if (initialCapacity < 0) {
throw new IllegalArgumentException("Capacity must be non-negative");
}
// Capacity is doubled when growing the array, so ensure it is at least
// 1.
elts = new String[Math.max(initialCapacity, 1)];
}

/**
* Sets the sequence of characters to be used when determining the string
* representation of this {@code StringJoiner} and no elements have been
Expand Down
97 changes: 95 additions & 2 deletions src/java.base/share/classes/java/util/stream/Collector.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.LongFunction;
import java.util.function.Supplier;

// A compilation test for the code snippets in this class-level javadoc can be found at:
Expand Down Expand Up @@ -206,6 +208,19 @@ public interface Collector<T, A, R> {
*/
Supplier<A> supplier();

/**
* A function that creates and returns a new mutable result container given
* the exact number of input elements or {@code -1} if not known.
*
* @implSpec The default implementation returns a function that returns the
* result of calling {@link #supplier()}.
*
* @return a function which returns a new, mutable result container
*/
default LongFunction<A> sizedSupplier() {
return _ -> supplier().get();
}

/**
* A function that folds a value into a mutable result container.
*
Expand Down Expand Up @@ -273,7 +288,7 @@ public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
? Collectors.CH_ID
: Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,
characteristics));
return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, cs);
return Collectors.CollectorImpl.ofUnsized(supplier, accumulator, combiner, cs);
}

/**
Expand Down Expand Up @@ -308,7 +323,85 @@ public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
Collections.addAll(cs, characteristics);
cs = Collections.unmodifiableSet(cs);
}
return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
return Collectors.CollectorImpl.ofUnsized(supplier, accumulator, combiner, finisher, cs);
}

/**
* Returns a new {@code Collector} described by the given {@code supplier},
* {@code sizedSupplier}, {@code accumulator}, and {@code combiner} functions.
* The resulting {@code Collector} has the
* {@code Collector.Characteristics.IDENTITY_FINISH} characteristic.
*
* @param supplier The supplier function for the new collector if the stream
* size is unknown
* @param sizedSupplier The function which returns a new result container
* of the appropriate size if the stream size is known
* @param accumulator The accumulator function for the new collector
* @param combiner The combiner function for the new collector
* @param characteristics The collector characteristics for the new
* collector
* @param <T> The type of input elements for the new collector
* @param <R> The type of intermediate accumulation result, and final result,
* for the new collector
* @throws NullPointerException if any argument is null
* @return the new {@code Collector}
*/
public static<T, R> Collector<T, R, R> ofSized(Supplier<R> supplier,
IntFunction<R> sizedSupplier,
BiConsumer<R, T> accumulator,
BinaryOperator<R> combiner,
Characteristics... characteristics) {
Objects.requireNonNull(supplier);
Objects.requireNonNull(sizedSupplier);
Objects.requireNonNull(accumulator);
Objects.requireNonNull(combiner);
Objects.requireNonNull(characteristics);
Set<Characteristics> cs = (characteristics.length == 0)
? Collectors.CH_ID
: Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,
characteristics));
return Collectors.CollectorImpl.of(supplier, sizedSupplier, accumulator, combiner, cs);
}

/**
* Returns a new {@code Collector} described by the given {@code supplier},
* {@code sizedSupplier}, {@code accumulator}, {@code combiner}, and
* {@code finisher} functions.
*
* @param supplier The supplier function for the new collector if the stream
* size is unknown
* @param sizedSupplier The function which returns a new result container
* of the appropriate size if the stream size is known
* @param accumulator The accumulator function for the new collector
* @param combiner The combiner function for the new collector
* @param finisher The finisher function for the new collector
* @param characteristics The collector characteristics for the new
* collector
* @param <T> The type of input elements for the new collector
* @param <A> The intermediate accumulation type of the new collector
* @param <R> The final result type of the new collector
* @throws NullPointerException if any argument is null
* @return the new {@code Collector}
*/
public static<T, A, R> Collector<T, A, R> ofSized(Supplier<A> supplier,
IntFunction<A> sizedSupplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A, R> finisher,
Characteristics... characteristics) {
Objects.requireNonNull(supplier);
Objects.requireNonNull(sizedSupplier);
Objects.requireNonNull(accumulator);
Objects.requireNonNull(combiner);
Objects.requireNonNull(finisher);
Objects.requireNonNull(characteristics);
Set<Characteristics> cs = Collectors.CH_NOID;
if (characteristics.length > 0) {
cs = EnumSet.noneOf(Characteristics.class);
Collections.addAll(cs, characteristics);
cs = Collections.unmodifiableSet(cs);
}
return Collectors.CollectorImpl.of(supplier, sizedSupplier, accumulator, combiner, finisher, cs);
}

/**
Expand Down
Loading