Why they integrate stream API to collection framework in java 8
Because before Java 8, Java collections features had a strong delay on concurrent languages such as C#, Scala, Ruby, etc... that provides out of the box and most of time in a conciser way a rich set of functional methods for collections but also pipeline processing for collections.
Thus I wonder why the java8 team made the decision to integrate Stream
API into the existing Collections framework instead of using
delegation (construct a Stream based on the given Collection)?
It would make the API of Stream less fluent, with more boiler plate code and as a consequence, it would not make intrinsically evolve the Java Collections features.
Imagine writing this code with a wrapper at each time :
List<String> strings = new ArrayList<>();
...
Streams.stream(strings).filter(....);
instead of :
List<String> strings = new ArrayList<>();
...
strings.stream().filter(....);
Imagine with a chained stream :
List<Integer> listOne = new ArrayList<>();
List<Integer> listTwo = new ArrayList<>();
...
List<int[]> values = Streams.stream(listOne)
.flatMap(i -> Streams.stream(listTwo)
.map(j -> new int[] { i, j }))
.collect(Collectors.toList());
instead of
List<Integer> listOne = new ArrayList<>();
List<Integer> listTwo = new ArrayList<>();
...
List<int[]> values = listOne.stream()
.flatMap(i -> listTwo.stream()
.map(j -> new int[] { i, j }))
.collect(Collectors.toList());
Especially by doing so, they have to introduce the new concept of
Interface's default method implementation that in turn, blur out the
semantic of Interfaces vs. Abstract classes?
It may be disconcerting at the beginning but finally it gives a powerful way to make evolve an API without breaking the client code using the old API.
Default methods should not be considered as a way to create abstract classes with common processings for all subclasses but a way to make evolve an API without breaking the compatibility with clients of older versions of the API.
Extract of the documentation on default methods :
Default methods enable you to add new functionality to the interfaces
of your libraries and ensure binary compatibility with code written
for older versions of those interfaces.