1

I have two lists as follow

List<String> color = new ArrayList<>();
        color.add("red");
        color.add("white");
        color.add("pink");

List<Specification> specList = new ArrayList<>();
Specification soundSystem = new Specification("MusicSysten", "harman Kardon");
Specification price = new Specification("Price", "50000");

specList.add(soundSystem);
specList.add(price);

I want to create a new instance of specification object for each color item and add that to the specList. I tried something like this, But it's not working.

List<Specification> output = color.stream().map(c -> specList.add(new Specification("color", c))).collect(Collectors.toList());

the output I want here is something like

List<List<Specification>> output = [[(new Specification("MusicSysten", "harman Kardon"), new Specification("Price", "50000"), new Specification("Color", "red"))], [(new Specification("MusicSysten", "harman Kardon"), new Specification("Price", "50000"), new Specification("Color", "white"))], [(new Specification("MusicSysten", "harman Kardon"), new Specification("Price", "50000"), new Specification("Color", "pink"))] ]

Any suggestion?

1
  • Sorry, I originally misunderstood your question. Please check my updated answer. Commented Jul 4, 2020 at 22:20

5 Answers 5

1

@WJS solution will work. If you need the soundSystem and price to be added first though, you could make use of the foreach stream method. You could also initiate your ArrayList with the total size if its known.

color.stream()
     .map(c -> new Specification("color", c))
     .foreach(specList::add);
Sign up to request clarification or add additional context in comments.

1 Comment

may be my question wasn't very clear. Updated my question
1

Try this.

List<List<Specification>> output = color.stream()
    .map(c -> Stream.concat(specList.stream(), Stream.of(new Specification("color", c)))
        .collect(Collectors.toList()))
    .collect(Collectors.toList());
System.out.println(output);

result:

[[Specification(MusicSysten, harman Kardon), Specification(Price, 50000), Specification(color, red)], [Specification(MusicSysten, harman Kardon), Specification(Price, 50000), Specification(color, white)], [Specification(MusicSysten, harman Kardon), Specification(Price, 50000), Specification(color, pink)]]

Comments

1

You're mapping to a new Specification so the List should be of type, Specification. And you just map to an object and let the collector build the list. Then you add that list to the specList.

Note that if you just keep using the same existing objects of soundSystem and price this may cause problems unless they are supposed to be immutable. So I added a copy method to the Specification class to create new objects of each specification. And since List.of makes immutable lists, I passed that to ArrayList to create a regular list.

List<List<Specification>> output = color.stream()
        .map(c -> new ArrayList<>(List.of(soundSystem,copy(), price.copy(),
                new Specification("color", c))))
        .collect(Collectors.toList());

output.forEach(System.out::println);

Prints

[{MusicSysten, harman Kardon}, {Price, 50000}, {color, red}]
[{MusicSysten, harman Kardon}, {Price, 50000}, {color, white}]
[{MusicSysten, harman Kardon}, {Price, 50000}, {color, pink}]

Specification Class

class Specification {
    String attribute1;
    String attribute2;
    public Specification(String attribute1, String attribute2) {
        this.attribute1 = attribute1;
        this.attribute2 = attribute2;
    }
    public String toString() {
        return "{" + attribute1 + ", " + attribute2 + "}";  
    }
    
    public Specification copy() {
        return new Specification(this.attribute1, this.attribute2);
    }
}

4 Comments

may be my question wasn't very clear. Updated my question
Here you go. Hopefully it meets your requirements.
what do you intend by .copy()? why not use the price and soundSystem specs directly.. also seems like you can simplify to .flatMap(clr -> Stream.of(soundSytem, price, new Specification("color",clr)))
If I used those specs directly they would be the same object. I just didn't think that would be a good idea unless they are supposed to be immutable.
1

Based on your clarification, It looks like you want the following (assuming you are using java 9 or later and can use the convenient List.of factory method):

Stream.of("red", "white", "pink")
   .map(c -> List.of(
      new Specification("MusicSysten", "harman Kardon"),
      new Specification("Price", "50000"),
      new Specification("Color", c)
   )).collect(toList());

1 Comment

may be my question wasn't very clear. Updated my question
0

If you're using Java 9 or higher, you can try

List<List<Specification>> output = color.stream()
     .map(c -> List.of(soundSystem.copy(), price.copy(), new Specification("color", c)))
     .collect(Collectors.toList());

The copy() method on Specification class could be similar as @WJS has mentioned in his answer

Comments

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.