What you are doing may be the simplest way, provided your stream stays sequential—otherwise you will have to put a call to sequential() before forEach.
The reason the call to sequential() is necessary is that the code as it stands (forEach(targetLongList::add)) would be racy if the stream was parallel. Even then, it will not achieve the effect intended, as forEach is explicitly nondeterministic—even in a sequential stream the order of element processing is not guaranteed. You would have to use forEachOrdered to ensure correct ordering. The intention of the Stream API designers is that you will use collector in this situation, as below:
targetLongList = sourceLongList.stream()
.filter(l -> l > 100)
.collect(Collectors.toList());
Answer from Maurice Naftalin on Stack OverflowWhat you are doing may be the simplest way, provided your stream stays sequential—otherwise you will have to put a call to sequential() before forEach.
The reason the call to sequential() is necessary is that the code as it stands (forEach(targetLongList::add)) would be racy if the stream was parallel. Even then, it will not achieve the effect intended, as forEach is explicitly nondeterministic—even in a sequential stream the order of element processing is not guaranteed. You would have to use forEachOrdered to ensure correct ordering. The intention of the Stream API designers is that you will use collector in this situation, as below:
targetLongList = sourceLongList.stream()
.filter(l -> l > 100)
.collect(Collectors.toList());
One approach is to use Collectors.toList to collect the stream into a list:
targetLongList =
sourceLongList.stream().
filter(l -> l > 100).
collect(Collectors.toList());
If a specific List implementation is desired, Collectors.toCollection can be used instead:
targetLongList =
sourceLongList.stream().
filter(l -> l > 100).
collect(Collectors.toCollection(ArrayList::new));
Videos
The easiest method is to use the toArray(IntFunction<A[]> generator) method with an array constructor reference. This is suggested in the API documentation for the method.
String[] stringArray = stringStream.toArray(String[]::new);
It finds a method that takes in an integer (the size) as argument, and returns a String[], which is exactly what (one of the overloads of) new String[] does.
You could also write your own IntFunction:
Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);
The purpose of the IntFunction<A[]> generator is to convert an integer, the size of the array, to a new array.
Example code:
Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);
Prints:
a
b
c
If you want to get an array of ints, with values from 1 to 10, from a Stream<Integer>, there is IntStream at your disposal.
Here we create a Stream with a Stream.of method and convert a Stream<Integer> to an IntStream using a mapToInt. Then we can call IntStream's toArray method.
Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
//or use this to create our stream
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed();
int[] array = stream.mapToInt(x -> x).toArray();
Here is the same thing, without the Stream<Integer>, using only the IntStream:
int[]array2 = IntStream.rangeClosed(1, 10).toArray();
Assuming Person and User are types, rather than specific objects, you can do something like this.
return list.stream()
.filter(o -> !(o instanceof Person) && !(o instanceof User))
.findAny()
.isPresent() ? list : null;
Alternative to Paul's answer (with the if-else in your question)
if (arrayList.stream().allMatch(o -> o instanceof Person || o instanceof User)) {
return null;
} else {
return arrayList;
}