I have a Set<String>
of "hostname:port"
pairs and from that I'd like to create a Set<InetSocketAddress>
. I tried it like:
Set<InetSocketAddress> ISAAddresses = StrAddresses
.stream().map(addr -> new InetSocketAddress(
addr.split(":")[0],
Integer.parseInt(addr.split(":")[1])));
But this produces the following error in IntelliJ:
Incompatible types. Required
Set<InetSocketAddress>
but 'map' was inferred toStream<R>
: no instance(s) of type variable(s) R exist so thatStream<R>
conforms toSet<InetSocketAddress>
Something must be wrong with how I'm using the map and the lambda.
Set interface extends Collection interface and Collection has stream() method that returns a sequential stream of the collection. Below given are some examples to understand the implementation in a better way. Example 1 : Converting Integer HashSet to Stream of Integers. // Java code for converting. // Set to Stream.
Being a type of Collection, we can convert a set to Stream using its stream() method.
What are the two types of Streams offered by java 8? Explanation: Sequential stream and parallel stream are two types of stream provided by java.
The Stream#map
function does not return a Map
. It transforms (maps) the current elements of your stream to other elements. So it generates from a Stream<X>
a Stream<Y>
using the given transformation function which takes X
and outputs Y
.
StrAddresses.stream() // String
.map(addr -> new InetSocketAddress(
addr.split(":")[0],
Integer.parseInt(addr.split(":")[1]))); // InetSocketAddress
You start with a Stream<String>
and end up with a Stream<InetSocketAddress>
.
To quote from its documentation:
Returns a stream consisting of the results of applying the given function to the elements of this stream.
If you want to transform that stream into a Set
you need to use the Stream#collect
method like so:
StrAddresses.stream()
.map(addr -> new InetSocketAddress(
addr.split(":")[0],
Integer.parseInt(addr.split(":")[1])))
.collect(Collectors.toSet());
The utility method Collectors.toSet()
returns a collector for a well optimized Set
. If you for example explicitly want a HashSet
you can use this instead:
.collect(Collectors.toCollection(HashSet::new));
From its documentation:
Performs a mutable reduction operation on the elements of this stream. A mutable reduction is one in which the reduced value is a mutable result container, such as an
ArrayList
[...]
As a small note, you currently split the same element twice each time:
addr.split(":")[0], // First
Integer.parseInt(addr.split(":")[1]))) // Second
You could save that additional split
procedure by memorizing the value before. In this case this can be done elegantly by using a second Stream#map
call. First we transform from Stream<String>
to Stream<String[]>
and then to Stream<InetSocketAddress>
:
StrAddresses.stream() // String
.map(addr -> addr.split(":")) // String[]
.map(addrData -> new InetSocketAddress(
addrData[0], Integer.parseInt(addrData[1]))) // InetSocketAddress
.collect(Collectors.toSet());
Note that Stream#map
is a lazy operation. This means that Java will not transform the whole Stream
from A
to B
once you call the method. It will wait until a non-lazy (finalizing) operation like Stream#collect
comes, then traverse the Stream
and apply each lazy operation element-wise. So you can add as many Stream#map
calls as you like without producing extra loops over the whole Stream
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With