Collecting to a ConcurrentMap

If the collector returned by the Collectors.toMap() method is used in a parallel stream, the multiple partial maps created during parallel execution are merged by the collector to create the final result map. Merging maps can be expensive if keys from one map are merged into another. To address the problem, the Collectors class provides the three overloaded methods toConcurrentMap(), analogous to the three toMap() methods, that return a concurrent collector—that is, a collector that uses a single concurrent map to perform the reduction. A concurrent map is thread-safe and unordered. A concurrent map implements the java.util.concurrent.Concur-rentMap interface, which is a subinterface of java.util.Map interface (§23.7, p. 1482).

Using a concurrent map avoids merging of maps during parallel execution, as a single map is created that is used concurrently to accumulate the results from the execution of each substream. However, the concurrent map is unordered—any encounter order in the stream is ignored. Usage of the toConcurrentMap() method is illustrated by the following example of a parallel stream to create a concurrent map of CD titles released each year.

Click here to view code image

ConcurrentMap<Year, String> concMapYearToTitles = CD.cdList
    .parallelStream()
    .collect(Collectors.toConcurrentMap(CD::year, CD::title,
                                        (tt, t) -> tt + “:” + t));
//{2017=Java Jam:Java Jive, 2018=Lambda Dancing:Hot Generics:Keep on Erasing}

Joining

The joining() method creates a collector for concatenating the input elements of type CharSequence to a single immutable String. However, internally it uses a mutable StringBuilder. Note that the collector returned by the joining() methods performs functional reduction, as its result is a single immutable string.

Click here to view code image

static Collector<CharSequence,?,String> joining()
static Collector<CharSequence,?,String> joining(CharSequence delimiter)
static Collector<CharSequence,?,String> joining(CharSequence delimiter,
                                                CharSequence prefix,
                                                CharSequence suffix)

Return a Collector that concatenates CharSequence elements into a String. The first method concatenates in encounter order. So does the second method, but this method separates the elements by the specified delimiter. The third method in addition applies the specified prefix and suffix to the result of the concatenation.

The wildcard ? is a type parameter that is used internally by the collector.

The methods preserve the encounter order, if the stream has one.

Among the classes that implement the CharSequence interface are the String, StringBuffer, and StringBuilder classes.

The stream pipelines below concatenate CD titles to illustrate the three overloaded joining() methods. The CharSequence elements are Strings. The strings are concatenated in the stream encounter order, which is the positional order for lists. The zero-argument joining() method at (1) performs string concatenation of the CD titles using a StringBuilder internally, and returns the result as a string.

Click here to view code image

String concatTitles1 = CD.cdList.stream()         // Stream<CD>
    .map(CD::title)                               // Stream<String>
    .collect(Collectors.joining());               // (1)
//Java JiveJava JamLambda DancingKeep on ErasingHot Generics

The single-argument joining() method at (2) concatenates the titles using the specified delimiter.

Click here to view code image

String concatTitles2 = CD.cdList.stream()
    .map(CD::title)
    .collect(Collectors.joining(“, “));           // (2) Delimiter
//Java Jive, Java Jam, Lambda Dancing, Keep on Erasing, Hot Generics

The three-argument joining() method at (3) concatenates the titles using the specified delimiter, prefix, and suffix.

Click here to view code image

String concatTitles3 = CD.cdList.stream()
    .map(CD::title)
    .collect(Collectors.joining(“, “, “[“, “]”));  // (3) Delimiter, Prefix, Suffix
//[Java Jive, Java Jam, Lambda Dancing, Keep on Erasing, Hot Generics]

Leave a Reply

Your email address will not be published. Required fields are marked *