If you copied your line 2 correctly, then it is incorrect and will fail to compile. My line 4 has, on the other hand, the correct types and will run correctly when you correct the minorr spellling misstakes.
Let's go through my version of your code. Lines 1‑2 create a
List<String>.
List#of() has overloadings and in this case it creates a 6‑element
unmodifiable List. All the arguments should be of the same type (otherwise you would probably get a
List<Object>), and in this case they are all Strings, so you get a
List<String>.
That should be pronounced, “List of Strings.”
So far, so good.
See the
Collection#stream() method. Line 4 does nothing until the terminal operation (line 6) runs. That is called lazy execution. If line 6 runs (and it does), then line 4 creates a
Stream<String> which manipulates all the elements of the List in turn.
Look at
Stream#limit(). That takes a
long and produces a new
Stream of the same type, but in this case it only has four elements. Since you are using one sequential
Stream, that is done very simply by taking the first four elements. The link tells you that things can become more complicated if you use parallel
Streams. Yes, you are using
4L if you pass an
int because the
limit() method will convert the 4 to a
long. That's
4L.
Line 6 is a terminal operation because it doesn't create another
Stream. If you look up
collect(), you will find it takes a
Collector. You can write your own
Collector in three or four parts, but if you look in the
Collectors class, you will find a method returning one ready‑made:
here. So you call that and the
Collector returned produces a
List. It doesn't specify what sort of
List however.
The remainder of the code should be obvious.