3

I have a class Test

public class Test{
  String codes;
  String field 1;
  ....
  String field n;
}

I have a list of test objects

List<Test> objects, code can be one or more with a comma separated
testObj1("A", "field1".."fieldn")
testObj2("B,C", ...)
testObj3("D,E,F", ....)
testObj4("G", ...)

Trying to convert this list1 to new list2 with each code A, B, C... to its own object by retaining the remaining fields.

List<Test>
testObj1("A", ....)
testObj2("B", ....)
testObj3("C", ....)

list1.stream().collect(Collectors.toList())

I achieved this using loops (Sudo code) but looking for better logic

for(loop thru list1){
  String[] codesArr = testObj1.codes.split(",");
  for (String code : codesArr) {
    //Create new Obj 
    Test obj = new Test(code, testObj1.copyotherfields);
    //Add obj to list2
  }
}
3
  • 1
    What do you mean by "better"? Commented Jan 17, 2019 at 21:35
  • I meant using Java Streams Commented Jan 18, 2019 at 15:11
  • In the future, please be explicit about what you are asking for. I cannot know by your question whether there were performance issues, memory issues, correctness issues... Commented Jan 18, 2019 at 18:30

3 Answers 3

3

You can use Stream.map with flatMap as :

List<Test> finalList = list1.stream()
        .flatMap(e -> Arrays.stream(e.getCodes().split(","))
                .map(c -> new Test(c, e.getField1(), e.getFieldn())))
        .collect(Collectors.toList());

This assumes that your Test class would have a constructor similar to the following implementation:

class Test {
    String codes;
    String field1;
    String fieldn;

    // would vary with the number of 'field's
    Test(String codes, String field1, String fieldn) {
        this.codes = codes;
        this.field1 = field1;
        this.fieldn = fieldn;
    }
    // getters and setters
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can simplify this to:

List<Test> copy = list.stream()
                      .map(e -> Arrays.stream(e.codes.split(""))            
                                      .map(c -> new Test(c, e.otherField))
                     .collect(Collectors.toList()))
                     .findAny().orElse(...);

Which will stream through the given list, then stream through the Array yielded from split() and map to a new Test object and collect it to a List. It retrieves it through findAny(), which returns an Optional<List<Test>>, so I would recommend using orElse to retrieve a default value.

Comments

-1

You can use a map function and then flatMap it to be like so:

List<String> testList = Arrays.asList("one,two,three,four", "five", "six", "seven", 
"eight, nine", "ten");

 List<String> reMappedList = testList.stream()
 .map(s -> {
     String[] array = s.split(",");
     return Arrays.asList(array);
 })
 .flatMap(List::stream)
 .collect(Collectors.toList());

 System.out.println(reMappedList);

1 Comment

I believe OP wanted a List<Test> not a List<String>

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.