Reputation: 187
I have a list of array of 2 objects:
List<Object[2]>
Where object[0] is an Integer and object[1] is a String.
How can I stream the list and apply different functions on each object? So that, the result will be an array having:
result[0] = multiplication of all object[0]
result[1] = concatenation of all object[1]
Upvotes: 11
Views: 8371
Reputation: 298439
With JDK-12, you can use
Object[] array = list.stream()
.collect(Collectors.teeing(
Collectors.reducing(1, a -> (Integer)a[0], (a,b) -> a * b),
Collectors.mapping(a -> (String)a[1], Collectors.joining()),
(i,s) -> new Object[] { i, s}
));
but you really should rethink your data structures.
This answer shows a version of the teeing
collector which works under Java 8.
Upvotes: 11
Reputation: 140543
You already got a good technical answer, so let's add a distinct non-answer.
This here: List<Object[2]>
feels sooooo wrong.
Why don't you use something like: List<Pair<Integer, String>>
?!
In other words: do not give up on type information lightly. Do not misuse Object[]
as a typeless container to stuff in already typed things. Java is a statically compiled language. Meaning: don't resist the forces of generics and strict typing, instead flow with them.
And the answer code turns into:
.reduce(p1, p2 -> new Pair<>(p1.first * p2.first, p1.second + p2.second))
Seriously: it starts by using Object[]
... and it ends with you switching to ruby 'cause dynamic typing!
Upvotes: 8
Reputation: 822
You can achieve this with reduce()
:
public void testStacko() {
List<Object[]> list = new ArrayList<>();
list.add(new Object[] {1, "foo"});
list.add(new Object[] {6, "|bar"});
list.add(new Object[] {15, "|baz"});
Object[] array = list.stream()
.reduce(
(obj1, obj2) ->
new Object[] {(int) obj1[0] * (int) obj2[0],
(String) obj1[1] + (String) obj2[1]
}
)
.get();
System.out.println(array[0]); // 90
System.out.println(array[1]); // foo|bar|baz
}
Upvotes: 12