Ich habe einen Klassentest

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

Ich habe eine Liste von Testobjekten

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", ...)

Der Versuch, dieses list1 mit jedem Code A, B, C ... in ein neues list2 in ein eigenes Objekt zu konvertieren, indem die verbleibenden Felder beibehalten werden.

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

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

Ich habe dies mit Schleifen (Sudo-Code) erreicht, aber nach einer besseren Logik gesucht

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
user08152017 18 Jän. 2019 im 00:21

3 Antworten

Beste Antwort

Sie können Stream.map mit flatMap verwenden als:

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

Dies setzt voraus, dass Ihre Test -Klasse einen Konstruktor hat, der der folgenden Implementierung ähnelt:

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
}
3
Naman 18 Jän. 2019 im 10:22

Sie können dies vereinfachen, um:

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

Das wird durch die angegebene Liste streamen, dann durch das Array, das von split() stammt, streamen und einem neuen Test Objekt zuordnen und es einem List sammeln. Es ruft es über findAny() ab, das ein Optional<List<Test>> zurückgibt. Daher würde ich empfehlen, orElse zu verwenden, um einen Standardwert abzurufen.

0
GBlodgett 18 Jän. 2019 im 00:51

Sie können eine map Funktion verwenden und dann flatMap so aussehen:

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
Blake Ordway 17 Jän. 2019 im 21:59