8019401: Collectors.collectingAndThen
Reviewed-by: mduigou
This commit is contained in:
parent
d2956c2e8d
commit
4030ed819b
@ -353,6 +353,43 @@ public final class Collectors {
|
|||||||
downstream.characteristics());
|
downstream.characteristics());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapts a {@code Collector} to perform an additional finishing
|
||||||
|
* transformation. For example, one could adapt the {@link #toList()}
|
||||||
|
* collector to always produce an immutable list with:
|
||||||
|
* <pre>{@code
|
||||||
|
* List<String> people
|
||||||
|
* = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList));
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param <T> the type of the input elements
|
||||||
|
* @param <A> intermediate accumulation type of the downstream collector
|
||||||
|
* @param <R> result type of the downstream collector
|
||||||
|
* @param <RR> result type of the resulting collector
|
||||||
|
* @param downstream a collector
|
||||||
|
* @param finisher a function to be applied to the final result of the downstream collector
|
||||||
|
* @return a collector which performs the action of the downstream collector,
|
||||||
|
* followed by an additional finishing step
|
||||||
|
*/
|
||||||
|
public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
|
||||||
|
Function<R,RR> finisher) {
|
||||||
|
Set<Collector.Characteristics> characteristics = downstream.characteristics();
|
||||||
|
if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
|
||||||
|
if (characteristics.size() == 1)
|
||||||
|
characteristics = Collectors.CH_NOID;
|
||||||
|
else {
|
||||||
|
characteristics = EnumSet.copyOf(characteristics);
|
||||||
|
characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
|
||||||
|
characteristics = Collections.unmodifiableSet(characteristics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new CollectorImpl<>(downstream.supplier(),
|
||||||
|
downstream.accumulator(),
|
||||||
|
downstream.combiner(),
|
||||||
|
downstream.finisher().andThen(finisher),
|
||||||
|
characteristics);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@code Collector} accepting elements of type {@code T} that
|
* Returns a {@code Collector} accepting elements of type {@code T} that
|
||||||
* counts the number of input elements. If no elements are present, the
|
* counts the number of input elements. If no elements are present, the
|
||||||
|
@ -25,6 +25,7 @@ package org.openjdk.tests.java.util.stream;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -52,6 +53,7 @@ import java.util.stream.TestData;
|
|||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import static java.util.stream.Collectors.collectingAndThen;
|
||||||
import static java.util.stream.Collectors.groupingBy;
|
import static java.util.stream.Collectors.groupingBy;
|
||||||
import static java.util.stream.Collectors.groupingByConcurrent;
|
import static java.util.stream.Collectors.groupingByConcurrent;
|
||||||
import static java.util.stream.Collectors.partitioningBy;
|
import static java.util.stream.Collectors.partitioningBy;
|
||||||
@ -603,4 +605,17 @@ public class TabulatorsTest extends OpTestCase {
|
|||||||
new PartitionAssertion<>(classifier,
|
new PartitionAssertion<>(classifier,
|
||||||
new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
|
new ReduceAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
|
||||||
|
public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
|
||||||
|
List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
|
||||||
|
List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
|
||||||
|
assertEquals(asList, asImmutableList);
|
||||||
|
try {
|
||||||
|
asImmutableList.add(0);
|
||||||
|
fail("Expecting immutable result");
|
||||||
|
}
|
||||||
|
catch (UnsupportedOperationException ignored) { }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user