Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Java Stream method equivalent to Scala's collections "collect"?

Scala's collection provides a method called collect that merges filter and map into a single method. It's particularly useful when filtering an Object collection to produce a subset of that collection containing only a particular type.

Is there any such thing with Java 8's Stream?

like image 735
Daniel C. Sobral Avatar asked Dec 19 '14 03:12

Daniel C. Sobral


People also ask

How do Java streams differ from collections?

Differences between a Stream and a Collection: A stream does not store data. An operation on a stream does not modify its source, but simply produces a result. Collections have a finite size, but streams do not.

Which is faster Stream or collection?

For this particular test, streams are about twice as slow as collections, and parallelism doesn't help (or either I'm using it the wrong way?).

How iterations are different between collections and streams?

Collections have to be iterated externally. Streams are internally iterated. Collections can be traversed multiple times. Streams are traversable only once.


1 Answers

Having a combination of filter and map in one step is not that useful in Java given its type system. E.g. there is no such PartialFunction type.

The closest thing is flatMap:

List<Object> list=Arrays.asList(0, "foo", 0L, 42.0, true, "false");
List<String> sList = list.stream()
  .flatMap(o-> o instanceof String? Stream.of((String)o): Stream.empty())
  .collect(Collectors.toList());
System.out.println(sList);

but the expressiveness of

.flatMap(o-> o instanceof String? Stream.of((String)o): Stream.empty())

is not that bigger compared to

.filter(o -> o instanceof String).map(o -> (String)o)

Of course, you may create a helper method encapsulating these steps in a single, undissolvable operation:

static <T> Stream<T> onlyType(Stream<?> s, Class<T> type) {
    return s.filter(type::isInstance).map(type::cast);
}

then you can use it like

List<String> sList=onlyType(list.stream(), String.class).collect(Collectors.toList());
like image 52
Holger Avatar answered Sep 23 '22 01:09

Holger