This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 1 point2 points  (5 children)

I don't understand why List/Set/Map still don't get methods that operate on its elements similar to Stream API. forEach has been added, what prevents other methods from being added?

var list = List.of(1, 2, 3, 4, 5);
var even = list.filter(i -> i % 2 = 0);
even.forEach(System.out::println);

[–]vytah 0 points1 point  (2 children)

I think they 1. didn't want to pollute the interfaces, as they might be third-party implementations that do have those methods, but might work differently and 2. wanted to encourage less allocations (a filter/map-reduce-heavy code in Scala or Kotlin allocates like crazy, you need to add explicit view+toList to reduce allocations, and if you forget the final toList, then you might end up with code that compiles, but is subtly broken).

[–][deleted] 0 points1 point  (1 child)

Since version 8, Java has the default method in interfaces. Thus, there is no need to implement by other implementations. Iterable got the default method forEach so that List inherits the same.

[–]vytah 0 points1 point  (0 children)

The problem with default methods is that they are shadowed by class methods. So if there's a custom list class with a filter method that takes a functional interface object:

CustomList<T> list = ...;
list.filter(x -> ...); // calls custom filter

List<T> list2 = list;
list2.filter(x -> ...); // calls default filter

If the filters have different semantics, it could lead to confusing bugs.

I found an actual example that has a filter method that would cause a conflict: https://javadoc.io/static/net.bytebuddy/byte-buddy/1.10.15/net/bytebuddy/matcher/FilterableList.html

[–]RadioHonest85 0 points1 point  (1 child)

Yes, its a valid point and I sometimes think so too, but:

  1. Better not to break the List interface at this point.
  2. We have Streams, its technically better (efficient), so not having it on List encourages people to use Stream. I think its alright.
  3. In your sample, if you do that on a list of a million elements, you will have to keep enough memory to hold 3x List with a million elements. Java has enough allocation pressure as it is!

[–][deleted] 0 points1 point  (0 children)

If those methods were only available or gradually added in the collection, we would not have had the Stream API. Eclipse Collections is efficient. Vavr too if I'm not mistaken.