下面列出了怎么用java.util.stream.Collector的API类实例代码及写法,或者点击链接到github查看源代码。
public void collector02Example(SqlClient client) {
// Create a collector projecting a row set to a (last_name_1,last_name_2,...)
Collector<Row, ?, String> collector = Collectors.mapping(
row -> row.getString("last_name"),
Collectors.joining(",", "(", ")")
);
// Run the query with the collector
client.query("SELECT * FROM users")
.collecting(collector)
.execute(ar -> {
if (ar.succeeded()) {
SqlResult<String> result = ar.result();
// Get the string created by the collector
String list = result.value();
System.out.println("Got " + list);
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
}
private<T, M extends Map>
void exerciseMapTabulation(TestData<T, Stream<T>> data,
Collector<T, ?, ? extends M> collector,
TabulationAssertion<T, M> assertion)
throws ReflectiveOperationException {
boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
M m = withData(data)
.terminal(s -> s.collect(collector))
.resultAsserter(mapTabulationAsserter(ordered))
.exercise();
assertion.assertValue(m, () -> data.stream(), ordered);
m = withData(data)
.terminal(s -> s.unordered().collect(collector))
.resultAsserter(mapTabulationAsserter(ordered))
.exercise();
assertion.assertValue(m, () -> data.stream(), false);
}
private<T, M extends Map>
void exerciseMapTabulation(TestData<T, Stream<T>> data,
Collector<T, ?, ? extends M> collector,
TabulationAssertion<T, M> assertion)
throws ReflectiveOperationException {
boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
M m = withData(data)
.terminal(s -> s.collect(collector))
.resultAsserter(mapTabulationAsserter(ordered))
.exercise();
assertion.assertValue(m, () -> data.stream(), ordered);
m = withData(data)
.terminal(s -> s.unordered().collect(collector))
.resultAsserter(mapTabulationAsserter(ordered))
.exercise();
assertion.assertValue(m, () -> data.stream(), false);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
// @@@ More things to test here:
// - Every value in data is present in right bucket
// - Total number of values equals size of data
for (MapperData<Integer, ?> md : getMapperData(data)) {
Collector<Integer, ?, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m);
Map<Object, List<Integer>> result =
withData(data)
.terminal(s -> s, s -> s.collect(tab))
.resultAsserter((act, exp, ord, par) -> {
if (par & !ord) {
GroupByOpTest.assertMultiMapEquals(act, exp);
}
else {
GroupByOpTest.assertObjectEquals(act, exp);
}
})
.exercise();
assertEquals(result.keySet().size(), md.expectedSize);
}
}
public void collector02Example(SqlClient client) {
// Create a collector projecting a row set to a (last_name_1,last_name_2,...)
Collector<Row, ?, String> collector = Collectors.mapping(
row -> row.getString("last_name"),
Collectors.joining(",", "(", ")")
);
// Run the query with the collector
client.query("SELECT * FROM users").collecting(collector).execute(ar -> {
if (ar.succeeded()) {
SqlResult<String> result = ar.result();
// Get the string created by the collector
String list = result.value();
System.out.println("Got " + list);
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
// @@@ More things to test here:
// - Every value in data is present in right bucket
// - Total number of values equals size of data
for (MapperData<Integer, ?> md : getMapperData(data)) {
Collector<Integer, ?, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m);
Map<Object, List<Integer>> result =
withData(data)
.terminal(s -> s, s -> s.collect(tab))
.resultAsserter((act, exp, ord, par) -> {
if (par & !ord) {
GroupByOpTest.assertMultiMapEquals(act, exp);
}
else {
GroupByOpTest.assertObjectEquals(act, exp);
}
})
.exercise();
assertEquals(result.keySet().size(), md.expectedSize);
}
}
@Test
public void testGetNameThatIsntUsed() throws InterruptedException, TimeoutException {
try (Session session = ds.getSession()) {
CompletionStage<Integer> idF = session.<Integer>rowOperation("select 100 as t")
.collect(Collector.of(
() -> new int[1],
(a, r) -> a[0] = r.at("notused").get(Integer.class),
(l, r) -> null,
a -> a[0])
)
.submit()
.getCompletionStage();
get10(idF);
fail("the column 'notused' doesn't exist in the result.row and should result in an IllegalArgumentException");
} catch (ExecutionException e) {
IllegalArgumentException ex = (IllegalArgumentException)e.getCause();
assertEquals("no column with id notused", ex.getMessage());
}
}
@Test(dataProvider = "maps")
public void testPutThenTraverse(String d, Map<HashCodeInteger, Integer> m) {
Collector<Integer, ?, ? extends Collection<Integer>> c = getCollector(m);
put(SIZE, m, (i, s) -> {
// Note that it is OK to collect to a Set (HashSet) as long as
// integer values are used since these tests only check for
// collisions and other tests will verify more general functionality
Collection<Integer> actual = m.keySet().stream().map(e -> e.value).collect(c);
Collection<Integer> expected = IntStream.range(0, s).boxed().collect(c);
assertEquals(actual, expected, "Map.keySet()");
});
}
default <R1, R2, A1, A2> Tuple2<R1, R2> collect(Collector<? super T, A1, R1> c1, Collector<? super T, A2, R2> c2) {
return stream().collect(Collector.of(() -> Tuple.tuple(c1.supplier().get(),c2.supplier().get()),
(t2, next) -> {
c1.accumulator().accept(t2._1(), next);
c2.accumulator().accept(t2._2(), next);
},(t2, t2b) -> Tuple.tuple(c1.combiner().apply(t2._1(), t2b._1()),c2.combiner().apply(t2._2(), t2b._2())),
t2 -> Tuple.tuple(c1.finisher().apply(t2._1()),c2.finisher().apply(t2._2()))));
}
public static <T, K, V> Collector<T, ImmutableMap.Builder<K, V>, ImmutableMap<K, V>> toImmutableMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper
) {
return Collector.of(
ImmutableMap.Builder<K, V>::new,
(r, t) -> r.put(keyMapper.apply(t), valueMapper.apply(t)),
(l, r) -> l.putAll(r.build()),
ImmutableMap.Builder::build,
Collector.Characteristics.UNORDERED
);
}
public MapCoercer(
Class<T> stereotype,
JsonTypeCoercer coercer,
Collector<Map.Entry<?, ?>, ?, ? extends T> collector) {
this.stereotype = stereotype;
this.coercer = coercer;
this.collector = collector;
}
/**
* Return a collector which calculates the bounds of a given way-point
* stream. The following example shows how to calculate the bounds of all
* track-points of a given GPX object.
*
* <pre>{@code
* final Bounds bounds = gpx.tracks()
* .flatMap(Track::segments)
* .flatMap(TrackSegment::points)
* .collect(Bounds.toBounds());
* }</pre>
*
* If the collecting way-point stream is empty, the collected {@code Bounds}
* object is {@code null}.
*
* @since 1.6
*
* @param <P> The actual point type
* @return a new bounds collector
*/
public static <P extends Point> Collector<P, ?, Bounds> toBounds() {
return Collector.of(
() -> {
final double[] a = new double[4];
a[0] = Double.MAX_VALUE;
a[1] = Double.MAX_VALUE;
a[2] = -Double.MAX_VALUE;
a[3] = -Double.MAX_VALUE;
return a;
},
(a, b) -> {
a[0] = min(b.getLatitude().doubleValue(), a[0]);
a[1] = min(b.getLongitude().doubleValue(), a[1]);
a[2] = max(b.getLatitude().doubleValue(), a[2]);
a[3] = max(b.getLongitude().doubleValue(), a[3]);
},
(a, b) -> {
a[0] = min(a[0], b[0]);
a[1] = min(a[1], b[1]);
a[2] = max(a[2], b[2]);
a[3] = max(a[3], b[3]);
return a;
},
a -> a[0] == Double.MAX_VALUE
? null
: Bounds.of(a[0], a[1], a[2], a[3])
);
}
public static <T, A, R> Collector<CompletableFuture<T>, ?, CompletableFuture<R>> toFuture(
Supplier<A> identitySupplier, BiFunction<T, A, A> reducer, BinaryOperator<A> combiner, Function<? super A, ? extends R> completer) {
return Collector.of(
() -> FutureReducer.of(identitySupplier.get(), reducer, combiner),
FutureReducer::addFuture,
FutureReducer::combine,
fr -> fr.complete().thenApply(completer));
}
@Test
public void testCollector(){
Collector<Integer, ?, List<Integer>> list = Collectors.toList();
List<Integer> res= null;
res =Stream.of(1,2,3)
.map(i->i+2)
.collect(list);
System.out.println("res " + res);
// Stream.of(1,2,3).collect((Supplier)list.supplier(),list.accumulator(),list.combiner());
}
/**
* Combines multiple {@code Optional-}returning collector cases, to collect to the first non-empty
* result. For example:
*
* <pre>{@code
* Name name = nameParts.stream()
* .collect(switching(
* when(QualifiedName::new), // (namespace, name) ->
* when(keywords::contains, Keyword::new), // (keyword) ->
* when(UnqualifiedName::) // (name) ->
* when(Anonymous::new))); // () ->
* }</pre>
*/
@SafeVarargs
public static <T, R> Collector<T, ?, R> switching(
Collector<? super T, ?, ? extends Optional<? extends R>>... cases) {
List<Collector<? super T, ?, ? extends Optional<? extends R>>> caseList =
Arrays.stream(cases).peek(Objects::requireNonNull).collect(toList());
return collectingAndThen(
toList(),
input ->
caseList.stream()
.map(c -> input.stream().collect(c).orElse(null))
.filter(v -> v != null)
.findFirst()
.orElseThrow(() -> unexpectedSize(input.size())));
}
public QueryExecutor(QueryTracer tracer,
ClientMetrics metrics,
Function<T, R> factory,
Collector<Row, ?, T> collector) {
this.tracer = tracer;
this.metrics = metrics;
this.factory = factory;
this.collector = collector;
}
@Override
public String toString() {
final Collector<CharSequence, ?, String> joiner;
if (fields.size() == 1)
joiner = Collectors.joining(", ");
else
joiner = Collectors.joining(", ", "(", ")");
return fields.stream()
.map(ResolverTuple::fieldString)
.collect(joiner);
}
@Override
public @Nullable Object parseParameter(Map<String, List<String>> parameters) throws MalformedValueException {
List<String> values = parameters.remove(parameterName);
if (values == null) return null;
return IntStream
.range(0, values.size())
.mapToObj(i -> parseItem(i, values.get(i)))
.flatMap(Function.identity())
.collect(Collector.of(JsonArray::new, JsonArray::add, JsonArray::addAll));
}
public static final Collector<WebuiRelatedProcessDescriptor, ?, JSONDocumentActionsList> collect(final JSONOptions jsonOpts)
{
final Supplier<List<WebuiRelatedProcessDescriptor>> supplier = ArrayList::new;
final BiConsumer<List<WebuiRelatedProcessDescriptor>, WebuiRelatedProcessDescriptor> accumulator = List::add;
final BinaryOperator<List<WebuiRelatedProcessDescriptor>> combiner = (l, r) -> {
l.addAll(r);
return l;
};
final Function<List<WebuiRelatedProcessDescriptor>, JSONDocumentActionsList> finisher = processDescriptors -> new JSONDocumentActionsList(processDescriptors, jsonOpts);
return Collector.of(supplier, accumulator, combiner, finisher);
}
@Override
public PluralFieldBuildProcessor<D, S, T, L> collect(Collector<T, ?, L> collector) {
if (this.collector != null)
throw new IllegalStateException("Can't call collector twice");
this.collector = (Collector<T, L, L>) collector;
return this;
}
/**
* Returns a collector which forms a JsonArray using the value mapper
*
* @param valueMapper the function to map from T to {@link JsonElement}
* @param <T> the type
* @return a new collector
*/
public static <T> Collector<T, JsonArrayBuilder, JsonArray> collectToArray(Function<? super T, JsonElement> valueMapper) {
return Collector.of(
JsonBuilder::array,
(r, t) -> r.add(valueMapper.apply(t)),
(l, r) -> l.addAll(r.build()),
JsonArrayBuilder::build
);
}
@Test
public void testMinMax() {
assertThrows(NullPointerException.class, () -> MoreCollectors.minMax(null, String::concat));
assertThrows(NullPointerException.class, () -> MoreCollectors.minMax(Comparator.naturalOrder(), null));
List<String> input = asList("abc", "a", "asdf", "gdasa", "gffsd", "sfgs", "b", "c", "dsgs");
checkCollector("minMax", Optional.of("agdasa"), input::stream, MoreCollectors.minMax(Comparator
.comparingInt(String::length), String::concat));
Collector<String, ?, Optional<Object>> collector = MoreCollectors.minMax(Comparator.naturalOrder(),
(min, max) -> {
throw new IllegalStateException("Should not be called");
});
checkCollectorEmpty("minMax", Optional.empty(), collector);
}
/**
* A collector which will convert a stream of {@link Measurement} instances into a {@link Model}.
*
* @return a {@link Collector} instance
*/
public static Collector<Measurement, List<Measurement>, Model> toModel() {
return Collector.of(
ArrayList::new,
List::add,
(a, b) -> {
a.addAll(b);
return a;
},
Model::build);
}
@Test
public void testOnlyIncluding() {
Collector<String, ?, List<String>> nullExcludingListCollector =
MoreCollectors.including(s -> s != null && s.length() > 1, toList());
List<String> pFruit = Stream.of(null, null, "Pineapple",
"Papaya", null, "Peach", "Plum", null,
"Pear")
.collect(nullExcludingListCollector);
assertEquals(
"Pineapple, Papaya, Peach, Plum, Pear",
pFruit.stream().collect(MoreCollectors.joining(", "))
);
}
/**
* Collect a single element.
*
* The Collector throws {@link IllegalArgumentException} if no or more than one element.
*
* @param <T> Element type
* @return The single element collector
*/
public static <T>
Collector<T, ?, T> single()
throws IllegalArgumentException
{
Supplier<T> thrower = () ->
{
throw new IllegalArgumentException( "No or more than one element in stream" );
};
return java.util.stream.Collectors.collectingAndThen( java.util.stream.Collectors.reducing( ( a, b ) -> null ),
optional -> optional.orElseGet( thrower ) );
}
private CollectorCtType newCollectorCtType(TypeMirror type) {
DeclaredType declaredType = getSuperDeclaredType(type, Collector.class);
if (declaredType == null) {
return null;
}
Iterator<? extends TypeMirror> typeArgs = declaredType.getTypeArguments().iterator();
CtType targetCtType = typeArgs.hasNext() ? newCtType(typeArgs.next()) : newNoneCtType();
@SuppressWarnings("unused")
CtType secondCtType = typeArgs.hasNext() ? newCtType(typeArgs.next()) : newNoneCtType();
CtType returnCtType = typeArgs.hasNext() ? newCtType(typeArgs.next()) : newNoneCtType();
return new CollectorCtType(ctx, type, targetCtType, returnCtType);
}
@Test(dataProvider = "maps")
public void testPutThenTraverse(String d, Map<HashCodeInteger, Integer> m) {
Collector<Integer, ?, ? extends Collection<Integer>> c = getCollector(m);
put(SIZE, m, (i, s) -> {
// Note that it is OK to collect to a Set (HashSet) as long as
// integer values are used since these tests only check for
// collisions and other tests will verify more general functionality
Collection<Integer> actual = m.keySet().stream().map(e -> e.value).collect(c);
Collection<Integer> expected = IntStream.range(0, s).boxed().collect(c);
assertEquals(actual, expected, "Map.keySet()");
});
}
@Test
public void testMapping() {
assertThrows(NullPointerException.class, () -> MoreCollectors.mapping(null, Collectors.toList()));
assertThrows(NullPointerException.class, () -> MoreCollectors.mapping(Function.identity(), null));
List<String> input = asList("Capital", "lower", "Foo", "bar");
Collector<String, ?, Map<Boolean, Optional<Integer>>> collector = MoreCollectors
.partitioningBy(str -> Character.isUpperCase(str.charAt(0)), MoreCollectors.mapping(String::length,
MoreCollectors.first()));
checkShortCircuitCollector("mapping", new BooleanMap<>(Optional.of(7), Optional.of(5)), 2, input::stream,
collector);
Collector<String, ?, Map<Boolean, Optional<Integer>>> collectorLast = MoreCollectors.partitioningBy(
str -> Character.isUpperCase(str.charAt(0)), MoreCollectors.mapping(String::length, MoreCollectors.last()));
checkCollector("last", new BooleanMap<>(Optional.of(3), Optional.of(3)), input::stream, collectorLast);
input = asList("Abc", "Bac", "Aac", "Abv", "Bbc", "Bgd", "Atc", "Bpv");
Map<Character, List<String>> expected = EntryStream.of('A', asList("Abc", "Aac"), 'B', asList("Bac", "Bbc"))
.toMap();
AtomicInteger cnt = new AtomicInteger();
Collector<String, ?, Map<Character, List<String>>> groupMap = Collectors.groupingBy(s -> s.charAt(0),
MoreCollectors.mapping(x -> {
cnt.incrementAndGet();
return x;
}, MoreCollectors.head(2)));
checkCollector("groupMap", expected, input::stream, groupMap);
cnt.set(0);
assertEquals(expected, input.stream().collect(groupMap));
assertEquals(4, cnt.get());
checkCollector("mapping-toList", asList("a", "b", "c"), asList("a1", "b2", "c3")::stream, MoreCollectors
.mapping(str -> str.substring(0, 1)));
}
public static <T> Collector<T, ?, Stream<T>> toOptimizedLazyShuffledStream() {
return Collectors.collectingAndThen(
toCollection(ArrayList::new),
list -> StreamSupport.stream(new ImprovedRandomSpliterator<>(list, Random::new), false));
}
/**
* Join a stream of code blocks into one code block, separated by the provided delimiter. Useful for joining an arbitrary
* number of method parameters, code statements, etc.
*/
public static Collector<CodeBlock, ?, CodeBlock> toDelimitedCodeBlock(String delimiter) {
return Collector.of(() -> new CodeBlockJoiner(delimiter), CodeBlockJoiner::add,
PoetCollectors::parallelNotSupported, CodeBlockJoiner::join);
}