Noor
Noor

Reputation: 187

Java Stream Reduce of array of objects

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

Answers (3)

Holger
Holger

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

GhostCat
GhostCat

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

Vincent Passau
Vincent Passau

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

Related Questions