1. Data conversion

The Stream<T> class also has a method that lets you convert data from one type to another. This method is map().

It also returns a stream, but with elements of a different type. The map() method takes as a method argument a function that converts one data type to another.

Examples:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stream2 = stream.map((x) -> String.valueOf(x));
Converting an Integer stream to a String stream

The function argument passed to the map() method takes a number x and returns its string representation. By the way, you can write this code more compactly:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stream2 = stream.map(String::valueOf);
Converting an Integer stream to a String stream

Converting a string to a number

Similarly, you can write code to convert a string to a number — this is also not complicated:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<String> stream2 = stream.map(String::valueOf);
Stream<Integer> stream3 = stream2.map(Integer::parseInt);
Converting a String stream to an Integer stream

Converting a string to a URI

Data conversion operations can be resource- and time intensive. Let's say we want to convert a collection of strings into URI objects. This is very easy to do, because the URI constructor takes a string as an argument.

ArrayList<String> list = new ArrayList<String>();
list.add("https://google.com");
list.add("https://linkedin.com");
list.add("https://yandex.com");

Stream<URI> stream = list.stream().map( URI::new );
Converting a String stream to a URI stream

We created a collection and populated it with 3 web addresses. Then we got a Stream<String> object from the collection, and in turn from that stream we got a Stream<URI> object. We passed the map method a reference to the method that will be used to convert each String to a URI.

This method (constructor) must take a String as an argument. Everything seems to be perfect...


2. Exceptions

We might expect that the code above should work, but it won't — the program won't compile. And not because we made a mistake somewhere, but because Java's creators messed up.

Once upon a time, they had the brilliant idea of adding a checked exception (URISyntaxException) to the URI class constructor! And such exceptions must be wrapped in a try-catch.

So the last line of our code will look like this:

Stream<URI> stream = list.stream().map(str ->
{
  try
  {
     return new URI(str);
  }
  catch (URISyntaxException e)
  {
     e.printStackTrace();
     return null;
  }
});

What can we say? You should think twice before using a checked exception. And think three times before using them in a constructor.