6

I have a question regarding Java streams. Let's say I have a stream of Object and I'd like to map each of these objects to multiple objects. For example something like

IntStream.range(0, 10).map(x -> (x, x*x, -x)) //...

Here I want to map each value to the same value, its square and the same value with opposite sign. I couldn't find any stream operation to do that. I was wondering if it would be better to map each object x to a custom object that has those fields, or maybe collect each value into intermediate Map (or any data structure).

I think that in terms of memory it could be better to create a custom object, but maybe I'm wrong.

In terms of design correctness and code clarity, which solution would be better? Or maybe there are more elegant solutions that I'm not aware of?

4
  • Try IntStream.range(0, 10).mapToObj(x -> new int[] {x, x*x, -x}). Commented Mar 16, 2018 at 1:42
  • But the object is of the same type of any type? Commented Mar 16, 2018 at 2:19
  • @JoseDaSilva not in my case, but from the answers I figure there are no direct way to do it anyway Commented Mar 16, 2018 at 5:36
  • Might be related. Commented Aug 6, 2023 at 21:55

2 Answers 2

5

You can use flatMap to generate an IntStream containing 3 elements for each of the elements of the original IntStream:

System.out.println(Arrays.toString(IntStream.range(0, 10)
                                            .flatMap(x -> IntStream.of(x, x*x, -x))
                                            .toArray()));

Output:

[0, 0, 0, 1, 1, -1, 2, 4, -2, 3, 9, -3, 4, 16, -4, 5, 25, -5, 6, 36, -6, 7, 49, -7, 8, 64, -8, 9, 81, -9]
Sign up to request clarification or add additional context in comments.

Comments

1

Besides using a custom class such as:

class Triple{
private Integer value;
public Triple(Integer value){
 this.value = value;
}

public Integer getValue(){return this.value;}
public Integer getSquare(){return this.value*this.value;}
public Integer getOpposite(){return this.value*-1;}
public String toString() {return getValue()+", "+this.getSquare()+", "+this.getOpposite();}
}

and run

IntStream.range(0, 10)
         .mapToObj(x -> new Triple(x))
         .forEach(System.out::println);

you could use apache commons InmmutableTriple to do so. for example:

 IntStream.range(0, 10)
.mapToObj(x -> ImmutableTriple.of(x,x*x,x*-1))
.forEach(System.out::println);

maven repo: https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.6

documentation: http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/ImmutableTriple.html

2 Comments

oh wow! an entire library for ImmutableTriple... when there is Arrays.asList or IntStream.of or List.of in java=9, etc
@eugene I mentioned before that, we could use a custom class as well. anyway, I added a custom class for reference.

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.