Chapters
Note: It's recommended to be knowledgeable about Stream Class before reading this article.
Collectors class that implement various useful reduction operations, such as accumulating elements into collections, summarizing elements according to various criteria, etc. Mostly all of the methods in this class return a Collector interface type. One of the forms of collect() method from Stream class accepts Collector type as argument.
My explanation here is simplified. Read the documentation for more information.
Method Form:
This method has two other variants:
This example demonstrate averagingInt().
Method form:
Adapts a Collector to perform an additional finishing transformation.
This example demonstrates collectingAndThen().
Method Form:
Returns a
This example demonstrates counting().
Method Form:
Adapts a Collector to one accepting elements of the same type T by applying the predicate to each input element and only accumulating if the predicate returns true. More information can be read in the documentation.
This example demonstrates filtering().
Method Form:
Adapts a Collector accepting elements of type U to one accepting elements of type T by applying a flat mapping function to each input element before accumulation. The flat mapping function maps an input element to a stream covering zero or more output elements that are then accumulated downstream.
Each mapped stream is closed after its contents have been placed downstream. If a mapped stream is null an empty stream is used, instead. More information can be read in the documentation.
This example demonstrates flatMapping().
Returns a Collector implementing a "group by" operation on input elements of type T, grouping elements according to a classification function. This method has three forms and I'm gonna demonstrate them one-by-one.
This example demonstrate this form:
public static <T, K> Collector<T,?,Map<K,List<T>>> groupingBy(Function<? super T,? extends K> classifier)
public static <T, K, D, A, M extends Map<K, D>> Collector<T,?,M> groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)
public static <T, K, A, D> Collector<T,?,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)
This example demonstrate groupingByConcurrent().
Returns a Collector that concatenates the input elements into a String, in encounter order. This method has three forms. I'll demonstrate them one-by-one.
This example demonstrates this form:
public static Collector<CharSequence,?,String> joining(CharSequence delimiter)
public static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
Method form:
Adapts a Collector accepting elements of type U to one accepting elements of type T by applying a mapping function to each input element before accumulation. More information can be read in the documentation.
This example demonstrates mapping().
Method Form:
Returns a Collector that produces the maximal element according to a given Comparator, described as an Optional<T>. More information can be read in the documentation.
This example demonstrates maxBy().
Method Form:
Returns a Collector that produces the minimal element according to a given Comparator, described as an Optional<T>. More information can be read in the documentation.
returns a Collector which partitions the input elements according to a Predicate, and organizes them into a
This method is similar to
This example demonstrates this form:
public static <T> Collector<T,?,Map<Boolean,List<T>>> partitioningBy(Predicate<? super T> predicate)
public static <T, D, A> Collector<T,?,Map<Boolean,D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)
Method Form:
Returns a Collector which performs a reduction of its input elements under a specified BinaryOperator. The result is described as an Optional<T>. This method has three forms. I'm gonna demonstrate them one-by-one.
This example demonstrates this form:
public static <T> Collector<T,?,Optional<T>> reducing(BinaryOperator<T> op)
public static <T> Collector<T,?,T> reducing(T identity, BinaryOperator<T> op)
Next, this example demonstrates this form:
public static <T, U> Collector<T,?,U> reducing(U identity, Function<? super T,? extends U> mapper, BinaryOperator<U> op)
Method Form:
Returns a Collector which applies an int-producing mapping function to each input element, and returns summary statistics for the resulting values.
This example demonstrates summarizingInt().
Method Form:
Returns a Collector that produces the sum of a numerical-valued function applied to the input elements. If no elements are present, the result is 0.
This example demonstrates summingInt().
Method Form:
Returns a Collector that is a composite of two downstream collectors. Every element passed to the resulting collector is processed by both downstream collectors, then their results are merged using the specified merge function into the final result.
More information can be read in the documentation.
This example demonstrates teeing().
Returns a Collector that accumulates elements into a Map whose keys and values are the result of applying the provided mapping functions to the input elements. More information can be read in the documentation.
This method has three forms. I'm gonna demonstrate them one-by-one. Also, examples here can be applied to other variants like
This example demonstrates this form:
public static <T, K, U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
public static <T, K, U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)
Next, this example demonstrates this form:
public static <T, K, U, M extends Map&tl;K, U>> Collector<T,?,M> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapFactory)
- Collectors Class
- averagingInt() and its Variants
- collectingAndThen() Method
- counting() Method
- filtering() Method
- flatMapping() Method
- groupingBy() and groupingByConcurrent() Methods
- joining() Method
- mapping() Method
- maxBy() Method
- minBy() Method
- partitioningBy() Method
- reducing() Method
- summarizingInt() and its Variants
- summingInt() and its Variants
- teeing() Method
- toMap() Method and other Variants
Collectors Class
Note: It's recommended to be knowledgeable about Stream Class before reading this article.
Collectors class that implement various useful reduction operations, such as accumulating elements into collections, summarizing elements according to various criteria, etc. Mostly all of the methods in this class return a Collector interface type. One of the forms of collect() method from Stream class accepts Collector type as argument.
My explanation here is simplified. Read the documentation for more information.
averagingInt() and its variants
Method Form:
averagingInt(ToIntFunction<? super T> mapper)
averagingInt()
Returns a Collector that produces the arithmetic mean of an integer-valued function applied to the input elements. If no elements are present, the result is 0.
This method has two other variants:
averagingDouble()
and averagingLong()
. This methods return arithmetic mean of a double-valued and long-valued functions respectively.
This example demonstrate averagingInt().
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(6); ar.add(8); ar.add(10); Double avg = ar.stream() .collect(Collectors .averagingInt((n) -> n*n)); //(2^2 + 4^2 + 6^2 + 8^2 + 10^2) / 5 //= 44 System.out.println("Result: "+avg); } } Result Result: 44.0
collectingAndThen() Method
Method form:
public static <T, A, R, RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)
Adapts a Collector to perform an additional finishing transformation.
This example demonstrates collectingAndThen().
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(6); ar.add(8); ar.add(10); Double avg = ar.stream() .collect( Collectors .collectingAndThen(Collectors .averagingInt((n) -> n*n), (nn) -> nn*nn); //(2^2 + 4^2 + 6^2 + 8^2 + 10^2) / 5 //= 44 //44^2 = 1936 System.out.println("Result: "+avg); } } Result Result: 1936.0In the example above,
averagingInt()
is applied first. Then, the finisher
is applied to the result of the downstream
.
counting() Method
Method Form:
public static <T> Collector<T,?,Long> counting()
Returns a
Collector
accepting elements of type T that counts the number of input elements. If no elements are present, the result is 0.
This example demonstrates counting().
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(6); ar.add(8); ar.add(10); Long count = ar.stream() .collect(Collectors.counting()); System.out.println("Result: " + count); } } Result: 5
filtering() Method
Method Form:
public static <T, A, R> Collector<T,?,R> filtering(Predicate<? super T> predicate,
Collector<? super T,A,R> downstream)
Adapts a Collector to one accepting elements of the same type T by applying the predicate to each input element and only accumulating if the predicate returns true. More information can be read in the documentation.
This example demonstrates filtering().
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(6); ar.add(8); ar.add(10); Double avg = ar.stream() .collect( Collectors.filtering( (t) -> t <= 6, Collectors.averagingInt( (n) -> n*n) ) ); //2^2 + 4^2 + 6^2 / 3 //= 18.666666666666668 System.out.println("Result: " + avg); } }
flatMapping() Method
Method Form:
public static <T, U, A, R> Collector<T,?,R> flatMapping(Function<? super T,? extends Stream<? extends U>> mapper, Collector<? super U,A,R> downstream)
Adapts a Collector accepting elements of type U to one accepting elements of type T by applying a flat mapping function to each input element before accumulation. The flat mapping function maps an input element to a stream covering zero or more output elements that are then accumulated downstream.
Each mapped stream is closed after its contents have been placed downstream. If a mapped stream is null an empty stream is used, instead. More information can be read in the documentation.
This example demonstrates flatMapping().
import java.util.stream.Collectors; import java.util.Arrays; import java.util.List; public class SampleClass{ public static void main(String[] args){ Integer[][] ints = {{2,4,6},{3,7,9}}; List<Integer> flatInts = Arrays.stream(ints) .collect( Collectors.flatMapping( (e) -> Arrays.stream(e), Collectors.toList()) ); for(Object o : flatInts) System.out.print(o + " "); } } Result 2 4 6 3 7 9
groupingBy() Method
Returns a Collector implementing a "group by" operation on input elements of type T, grouping elements according to a classification function. This method has three forms and I'm gonna demonstrate them one-by-one.
This example demonstrate this form:
public static <T, K> Collector<T,?,Map<K,List<T>>> groupingBy(Function<? super T,? extends K> classifier)
import java.util.stream.Collectors; import java.util.Map; import java.util.List; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(7); ar.add(8); ar.add(11); Map<String,List<Integer>> map = ar.stream() .collect(Collectors.groupingBy( (t) -> { if(t % 2 == 0) return "even"; else return "odd"; })); System.out.println(map); } } Result {even=[2, 4, 8], odd=[7, 11]}Next, This example demonstrate this form:
public static <T, K, D, A, M extends Map<K, D>> Collector<T,?,M> groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)
import java.util.stream.Collectors; import java.util.LinkedHashMap; import java.util.Set; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(7); ar.add(8); ar.add(11); LinkedHashMap<String,Set<Integer>> map = ar.stream() .collect(Collectors.groupingBy( (t) -> { if(t % 2 == 0) return "even"; else return "odd"; }, LinkedHashMap::new, Collectors.toSet())); System.out.println(map); } } Result {even=[2, 4, 8], odd=[7, 11]}Next, This example demonstrate this form:
public static <T, K, A, D> Collector<T,?,Map<K,D>> groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)
import java.util.stream.Collectors; import java.util.Map; import java.util.ArrayList; import java.util.function.Function; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("Banana"); ar.add("Apple"); ar.add("Carrot"); ar.add("Banana"); ar.add("Apple"); ar.add("Apple"); Map<String,Long> map = ar.stream() .collect(Collectors.groupingBy( Function.identity(), Collectors.counting() )); System.out.println(map); } } Result {Carrot=1, Apple=3, Banana=2}
Function.identity()
returns a function that always returns its input argument. This is useful if you don't wanna modify input arguments.
groupingByConcurrent()
is a variant of groupingBy()
method. These two are the same. Thus, the examples above can be applied to groupingByConcurrent()
. However, groupingByConcurrent()
is more optimized for concurrency especially for a huge collection of elements.
This example demonstrate groupingByConcurrent().
import java.util.stream.Collectors; import java.util.Map; import java.util.List; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(7); ar.add(8); ar.add(11); Map<String,List<Integer>> map = ar.parallelStream() .collect(Collectors.groupingByConcurrent( (t) -> { if(t % 2 == 0) return "even"; else return "odd"; })); System.out.println(map); } } Result(may vary) {even=[8, 4, 2], odd=[7, 11]}
joining() Method
Returns a Collector that concatenates the input elements into a String, in encounter order. This method has three forms. I'll demonstrate them one-by-one.
This example demonstrates this form:
public static Collector<CharSequence,?,String> joining()
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("A"); ar.add(" B"); ar.add(" C"); ar.add(" D"); String str = ar.stream() .collect(Collectors.joining()); System.out.println("Result: " + str); } } Result Result: A B C DNext, This example demonstrates this form:
public static Collector<CharSequence,?,String> joining(CharSequence delimiter)
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("A"); ar.add("B"); ar.add("C"); ar.add("D"); String str = ar.stream() .collect(Collectors.joining("-")); System.out.println("Result: " + str); } } Result Result: A-B-C-DNext, this example demonstrates this form:
public static Collector<CharSequence,?,String> joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
import java.util.stream.Collectors; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("A"); ar.add("B"); ar.add("C"); ar.add("D"); String str = ar.stream() .collect(Collectors.joining("-","^","*")); System.out.println("Result: " + str); } } Result Result: ^A-B-C-D*
mapping() Method
Method form:
public static <T, U, A, R> Collector<T,?,R> mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)
Adapts a Collector accepting elements of type U to one accepting elements of type T by applying a mapping function to each input element before accumulation. More information can be read in the documentation.
This example demonstrates mapping().
import java.util.stream.Collectors; import java.util.ArrayList; import java.util.List; import java.util.Map; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(7); ar.add(8); ar.add(11); Map<String, List<Integer>> map = ar.stream() .collect( Collectors.groupingBy( (t) -> { if(t % 2 == 0) return "even"; else return "odd"; }, Collectors.mapping( (t) -> t*t, Collectors.toList() ) )); System.out.println(map); } } Result {even=[4, 16, 64], odd=[49, 121]}
maxBy() Method
Method Form:
public static <T> Collector<T,?,Optional<T>*gt; maxBy(Comparator<? super T> comparator)
Returns a Collector that produces the maximal element according to a given Comparator, described as an Optional<T>. More information can be read in the documentation.
This example demonstrates maxBy().
import java.util.stream.Collectors; import java.util.ArrayList; import java.util.Optional; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("Joker"); ar.add("queen"); ar.add("jack"); ar.add("King"); Optional<String> opt = ar.stream().collect( Collectors.maxBy(String.CASE_INSENSITIVE_ORDER)); if(opt.isPresent()) System.out.println("max(last) index: " + opt.get()); else System.out.println("Empty result!"); } } Result max(last) index: queen
minBy() Method
Method Form:
public static <T> Collector<T,?,Optional<T>> minBy(Comparator<? super T> comparator)
Returns a Collector that produces the minimal element according to a given Comparator, described as an Optional<T>. More information can be read in the documentation.
import java.util.stream.Collectors; import java.util.ArrayList; import java.util.Optional; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("Joker"); ar.add("queen"); ar.add("jack"); ar.add("King"); Optional<String> opt = ar.stream().collect( Collectors.minBy(String.CASE_INSENSITIVE_ORDER)); if(opt.isPresent()) System.out.println("min(first) index: " + opt.get()); else System.out.println("Empty result!"); } } Result min(first) index: jack
partitioningBy() Method
returns a Collector which partitions the input elements according to a Predicate, and organizes them into a
Map
. The returned Map always contains mappings for both false and true keys. There are no guarantees on the type, mutability, serializability, or thread-safety of the Map or List returned.
This method is similar to
groupBy()
method. This method has two forms. I'm gonna demonstrate them one-by-one.
This example demonstrates this form:
public static <T> Collector<T,?,Map<Boolean,List<T>>> partitioningBy(Predicate<? super T> predicate)
import java.util.stream.Collectors; import java.util.Map; import java.util.List; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<Integer> ar = new ArrayList<>(); ar.add(2); ar.add(4); ar.add(7); ar.add(8); ar.add(11); Map<Boolean,List<Integer>> map = ar.stream() .collect(Collectors.partitioningBy( (t) -> { if(t % 2 == 0) return true; else return false; })); System.out.println(map); } } Result {false=[7, 11], true=[2, 4, 8]}Next, this example demonstrates this form:
public static <T, D, A> Collector<T,?,Map<Boolean,D>> partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)
import java.util.stream.Collectors; import java.util.Map; import java.util.Set; import java.util.ArrayList; public class SampleClass{ public static void main(String[] args){ ArrayList<String> ar = new ArrayList<>(); ar.add("Banana"); ar.add("Pork"); ar.add("Bacon"); ar.add("Quasar"); ar.add("Bamboo"); Map<Boolean,Set<String>> map = ar.stream() .collect(Collectors.partitioningBy( (t) -> t.startsWith("B"), Collectors.toSet())); System.out.println(map); } } Result {false=[Quasar, Pork], true=[Bacon, Bamboo, Banana]}As you can see,
partinioningBy()
is closely similar to groupingBy()
. Although, in my opinion, It's better to use partinioningBy()
if we want to separate elements only into two sections. For separating elements into multiple sections, use groupingBy()
.
reducing() Method
Method Form:
public static <T> Collector<T,?,Optional<T>> reducing(BinaryOperator<T> op)
Returns a Collector which performs a reduction of its input elements under a specified BinaryOperator. The result is described as an Optional<T>. This method has three forms. I'm gonna demonstrate them one-by-one.
This example demonstrates this form:
public static <T> Collector<T,?,Optional<T>> reducing(BinaryOperator<T> op)
import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.Optional; public class SampleClass{ public static void main(String[] args){ Stream<Integer> ints = Stream.of(2,4,6); Optional<Integer> opt = ints.collect( Collectors.reducing((t,u) -> (t*t)+(u*u))); if(opt.isPresent()) //(2*2 + 4*4)*(2*2 + 4*4) + 6*6 //(20*20) + 36 //400 + 36 //=436 System.out.println("SquaredThenAdd: " + opt.get()); else System.out.println("Empty result!"); } } Result: SquaredThenAdd: 436Next, this example demonstrates this form:
public static <T> Collector<T,?,T> reducing(T identity, BinaryOperator<T> op)
import java.util.stream.Collectors; import java.util.stream.Stream; public class SampleClass{ public static void main(String[] args){ Stream<Integer> ints = Stream.of(4,6); Integer result = ints.collect( Collectors.reducing(2, (t,u) -> (t*t)+(u*u))); //(2*2 + 4*4)*(2*2 + 4*4) + 6*6 //(20*20) + 36 //400 + 36 //=436 System.out.println("SquaredThenAdd: " + result); } } Result: SquaredThenAdd: 436
identity
parameter denotes initial value.Next, this example demonstrates this form:
public static <T, U> Collector<T,?,U> reducing(U identity, Function<? super T,? extends U> mapper, BinaryOperator<U> op)
import java.util.stream.Collectors; import java.util.stream.Stream; public class SampleClass{ public static void main(String[] args){ Stream<Integer> ints = Stream.of(2,4,6); Integer result = ints.collect( Collectors .reducing(0, (t) -> t*t, (t,u) -> t+u)); //2*2 + 4*4 + 6*6 = 56 System.out.println("SquaredThenAdd: " + result); } } Result: SquaredThenAdd: 56
summarizingInt() and its Variants
Method Form:
public static <T> Collector<T,?,IntSummaryStatistics> summarizingInt(ToIntFunction<? super T> mapper)
Returns a Collector which applies an int-producing mapping function to each input element, and returns summary statistics for the resulting values.
summarizingInt()
returns IntSummaryStatistics. Other variants like summarizingDouble()
and summarizingLong()
return DoubleSummaryStatistics and LongSummaryStatistics respectively.
This example demonstrates summarizingInt().
import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.IntSummaryStatistics; public class SampleClass{ public static void main(String[] args){ Stream<Integer> ints = Stream.of(2,4,6); IntSummaryStatistics iss = ints.collect( Collectors .summarizingInt((t) -> t*t)); System.out.println("Records"); System.out.println(iss + "\n"); } } Result Records IntSummaryStatistics {count=3, sum=56, min=4, average=18.666667, max=36}
summingInt() and its Variants
Method Form:
public static <T> Collector<T,?,Integer> summingInt(ToIntFunction<? super T> mapper)
Returns a Collector that produces the sum of a numerical-valued function applied to the input elements. If no elements are present, the result is 0.
summingInt()
returns Integer. Other variants like summingDouble()
and summingLong()
return Double and Long respectively.
This example demonstrates summingInt().
import java.util.stream.Collectors; import java.util.stream.Stream; public class SampleClass{ public static void main(String[] args){ Stream<Integer> ints = Stream.of(2,4,6); Integer result = ints.collect( Collectors .summingInt((t) -> t*t)); System.out.println("Value: " + result); } } Result Value: 56
teeing() Method
Method Form:
public static <T, R1, R2, R> Collector<T,?,R> teeing(Collector<? super T,?,R1> downstream1, Collector<? super T,?,R2> downstream2, BiFunction<? super R1,? super R2,R> merger)
Returns a Collector that is a composite of two downstream collectors. Every element passed to the resulting collector is processed by both downstream collectors, then their results are merged using the specified merge function into the final result.
More information can be read in the documentation.
This example demonstrates teeing().
import java.util.stream.Collectors; import java.util.stream.Stream; public class SampleClass{ public static void main(String[] args){ Stream<Integer> ints = Stream.of(2,4,6); Integer result = ints.collect( Collectors .teeing( Collectors.summingInt((t) -> t*t), Collectors.summingInt((t) -> t+t), (t,u) -> t+u)); //(2*2 + 4*4 + 6*6) + (2+2 + 4+4 + 6+6) //= 56 + 24 = 80 System.out.println("Value: " + result); } }
toMap() Method and other Variants
Returns a Collector that accumulates elements into a Map whose keys and values are the result of applying the provided mapping functions to the input elements. More information can be read in the documentation.
This method has three forms. I'm gonna demonstrate them one-by-one. Also, examples here can be applied to other variants like
toConcurrentMap()
and toUnmodifiableMap()
.
This example demonstrates this form:
public static <T, K, U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)
import java.util.stream.Collectors; import java.util.Arrays; import java.util.Map; public class SampleClass{ public static void main(String[] args){ String[][] strings = new String[][]{{"key1","val1"}, {"key2","val2"}, {"key3","val3"}}; Map<String,String> map = Arrays.stream(strings).collect( Collectors .toMap((t) -> t[0], (t) -> t[1])); System.out.println(map); } } Result {key1=val1, key2=val2, key3=val3}Next, this example demonstrates this form:
public static <T, K, U> Collector<T,?,Map<K,U>> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)
import java.util.stream.Collectors; import java.util.Arrays; import java.util.Map; public class SampleClass{ public static void main(String[] args){ String[][] strings = new String[][]{{"key1","val1"}, {"key2","val2"}, {"key1","val3"}}; Map<String,String> map = Arrays.stream(strings).collect( Collectors .toMap((t) -> t[0], (t) -> t[1], (t,u) -> t+"-"+u)); System.out.println(map); } } Result {key1=val1-val3, key2=val2}
mergeFunction
can merge the values of two duplicate keys. In the example above, val1
and val3
had been merged as one value of key1
with "-" delimiter.
Next, this example demonstrates this form:
public static <T, K, U, M extends Map&tl;K, U>> Collector<T,?,M> toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapFactory)
import java.util.stream.Collectors; import java.util.Arrays; import java.util.TreeMap; public class SampleClass{ public static void main(String[] args){ String[][] strings = new String[][]{{"key1","val1"}, {"key3","val4"}, {"key2","val2"}, {"key1","val3"}}; TreeMap<String,String> map = Arrays.stream(strings).collect( Collectors .toMap((t) -> t[0], (t) -> t[1], (t,u) -> t+"-"+u, TreeMap::new)); System.out.println(map); } } Result {key1=val1-val3, key2=val2, key3=val4}This example is not applicable to
toUnmodifiableMap()
because this form of toMap()
doesn't match(closely match) any form of toUnmodifiableMap()
.
No comments:
Post a Comment