How to create a custom collector in Java
How to create a custom collector in Java
brief introduction
In the previous Java collectors article, we mentioned that the collect method of stream can call the tolist () or tomap () method in collectors to convert the result into a specific collection class.
Today, we will introduce how to customize a collector.
Collector introduction
Let's first look at the definition of collector:
The collector interface needs to implement five interfaces: supplier(), accumulator(), combiner(), finisher(), characteristics().
At the same time, the collector also provides two static of methods to facilitate us to create a collector instance.
We can see that the parameters of the two methods correspond to the interface to be implemented by the collector interface one by one.
These parameters are explained below:
Supplier is a function used to create a new variable collection. In other words, supplier is used to create an initial collection. accumulator
The accumulator defines an accumulator to add the original to the collection.
Combiner is used to combine two sets into one.
Finisher converts the collection to the final collection type.
Characteristics represents the characteristics of the collection. This is not a required parameter.
With these parameters, let's see how to use these parameters to construct a custom collector.
Custom collector
We use the of method of the collector to create an invariant set:
public static <T> Collector<T,Set<T>,Set<T>> toImmutableSet() {
return Collector.of(HashSet::new,Set::add,(left,right) -> {
left.addAll(right);
return left;
},Collections::unmodifiableSet);
}
In the above example, we use HashSet:: new as the supplier and set:: add as the accumulator, and customize a method as the combiner. Finally, we use Collections:: unmodifiableset to convert the set into an immutable set.
In the above, we use HashSet:: new as the generation method of the initial set. In fact, the above method can be more general:
public static <T,A extends Set<T>> Collector<T,A,Set<T>> toImmutableSet(
supplier<A> supplier) {
return Collector.of(
supplier,Collections::unmodifiableSet);
}
In the above method, we propose supplier as a parameter and define it externally.
Take a look at the tests of the above two methods:
@Test
public void toImmutableSetUsage(){
Set<String> stringSet1=Stream.of("a","b","c","d")
.collect(ImmutableSetCollector.toImmutableSet());
log.info("{}",stringSet1);
Set<String> stringSet2=Stream.of("a","d")
.collect(ImmutableSetCollector.toImmutableSet(LinkedHashSet::new));
log.info("{}",stringSet2);
}
Output:
INFO com.flydean.ImmutableSetCollector - [a,b,c,d]
INFO com.flydean.ImmutableSetCollector - [a,d]