11

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]

3 Answers 3

12

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
}
Sign up to request clarification or add additional context in comments.

1 Comment

But it’s rather inefficient for larger lists.
12

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.

1 Comment

@GhostCat I always thought of a T connector or the Unix command tee. Don’t know whether “teeing” as a word predates that.
8

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!

4 Comments

I agree, it's much better with a Pair.
Because my list has more than 2 objects. I gave 2 objects list as an example. Pair definitely is better in the case of 2 objects.
@Noor then, any class type defining distinct fields with names and types is better than an array of differently typed elements whose meaning has to be guessed from their position.
@Holger agree. Am working on a POC right now and will have a class that will hold all of these objects. I Just wanted to know how to perform different functions on stream objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.