2016-10-14 3 views
3

Es gibt eine Liste A mit der Eigenschaft Entwickler. Entwickler-Schema mag das:Wie konvertiert man eine Liste mit Eigenschaften in eine andere Liste der Java 8-Wege?

@Getter 
@Setter 
public class Developer { 
    private String name; 
    private int age; 

    public Developer(String name, int age) { 
     this.name = name; 
     this.age = age; 
    } 

    public Developer name(String name) { 
     this.name = name; 
     return this; 
    } 

    public Developer name(int age) { 
     this.age = age; 
     return this; 
    } 
} 

Liste A mit den Eigenschaften:

List<Developer> A = ImmutableList.of(new Developer("Ivan", 25), new Developer("Curry", 28)); 

Es gefordert Liste A zu konvertieren B zur Liste, die mit Eigentum Produktmanager und die Eigenschaften sind das gleiche wie das der Liste A.

@Getter 
@Setter 
public class ProductManager { 
    private String name; 
    private int age; 

    public ProductManager(String name, int age) { 
     this.name = name; 
     this.age = age; 
    } 

    public ProductManager name(String name) { 
     this.name = name; 
     return this; 
    } 

    public ProductManager name(int age) { 
     this.age = age; 
     return this; 
    } 
} 

In den alten Tagen, würden wir Codes wie schreiben:

public List<ProductManager> convert() { 
    List<ProductManager> pros = new ArrayList<>(); 
    for (Developer dev: A) { 
     ProductManager manager = new ProductManager(); 
     manager.setName(dev.getName()); 
     manager.setAge(dev.getAge()); 
     pros.add(manager); 
    } 
    return pros; 
} 

Wie können wir das obige mit Java 8 eleganter und kurzer schreiben?

+3

Die eigentliche Frage hier ist, warum 'Developer' und' ProductManager' nicht scheinen von einer gemeinsamen Oberklasse "Person" zu erben, die "name" und "Alter" einkapselt. Bevor Sie auf die cleveren Java8-Glöckchen upgraden, sollten Sie das Design wahrscheinlich richtig machen. –

+0

@JimGarrison Ja, ich stimme Ihnen zu, ich muss mehr auf die Grundlagen achten. Wenn es mehr Eigenschaften gibt, vielleicht mehr als 20, und der Konstruktor kann nicht direkt verwenden, wie konvertiert man? – Ivan

+1

Wenn 'Developer' und' ProductManager' eine gemeinsame Basisklasse, 'Person', hatten, die alle allgemeinen Eigenschaften definiert, gab es kein Problem, einen Konstruktor mit einem' Person' Parameter in beiden Klassen zu definieren.Diese Konstruktoren würden nur an den Konstruktor der Basisklasse "Person" delegieren, die die Arbeit erledigt, also muss sie nur einmal implementiert werden. Beachten Sie, dass dies ein etabliertes Muster ist, d. H. Alle Standard-Collection-Typen stellen einen Konstruktor bereit, der ein Argument "Collection" akzeptiert, aus dem kopiert werden soll. – Holger

Antwort

4

Sie haben etwas zu verwenden, wie unten:

List<ProductManager> B = A.stream() 
     .map(developer -> new ProductManager(developer.getName(), developer.getAge())) 
     .collect(Collectors.toList()); 

// für große Anzahl der Eigenschaften unter der Annahme, die Attribute ähnlich haben Namen // andere weise mit anderen Namen beziehen sich this

List<ProductManager> B = A.stream().map(developer -> { 
      ProductManager productManager = new ProductManager(); 
      try { 
       PropertyUtils.copyProperties(productManager, developer); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 
      return productManager; 
     }).collect(Collectors.toList()); 

     B.forEach(System.out::println); 
+0

Wenn es mehr Eigenschaften, vielleicht mehr als 20, und der Konstruktor kann nicht direkt verwenden, wie konvertiert? – Ivan

+1

@Ivan hat ein Beispiel mit PropertyUtils hinzugefügt, scheint ein einfacher Weg zu sein –

0

Wahrscheinlich so:

List<ProductManager> B = A.stream() 
     .map(developer -> new ProductManager(developer.name, developer.age)) 
     .collect(Collectors.toList()); 
0

Wenn Sie sind fein Belwo Konstruktor in ProductManger

public ProductManager(Developer d) { 
    this.name = d.getName(); 
    this.age = d.getAge(); 
} 

dann hinzufügen Referenz verwendet Konstruktor konvertieren

List<Developer> developers = Arrays.asList(new Developer("abc", 25)); 
    List<ProductManager> managers = developers.stream().map(ProductManager::new).collect(Collectors.toList()); 
    System.out.println(managers); 

sonst können Sie zur Verfügung stellen benutzerdefinierte Mapper

Function<Developer, ProductManager> mapper = d -> new ProductManager(d.getName(), d.getAge()); 

Verwendung dieses in map Funktion

Ausgabe

[ProductManager [name=abc, age=25]] 
+0

Wenn es mehr Eigenschaften gibt, vielleicht mehr als 20, und der Konstruktor kann nicht direkt verwenden, wie konvertiert man? – Ivan

+0

In der obigen Mapper-Funktion anstelle von Konstruktor, erstellen Sie ein Produkt-Manager-Objekt, setzen Sie alle Eigenschaften und geben Sie – Saravana

0

Wenn es mehr Eigenschaften sind, vielleicht mehr als 20, und der Konstruktor kann nicht direkt verwendet werden, wie zu konvertieren?

Wenn Sie mehr als 3-4 Eigenschaften festlegen, sollten Sie einen Builder, etwa so:

List<Developer> A = ImmutableList.of(new Developer("Ivan", 25), 
            new Developer("Curry", 28)); 

Function<Developer, ProductManager> converter = dev -> new ProductManagerBuilder() 
     .setAge(dev.getAge()) 
     .setName(dev.getName()) 
     .setProperty1(dev.getProperty1()) 
     .setProperty2(dev.getProperty2()) 
     ... 
     .build(); 

List<ProductManager> productManagers = A.stream() 
             .map(converter) 
             .collect(toList()); 
+0

Sie wollen Build-Muster verwenden? Es ist richtig. Meine Frage war dann, wie man den Funktionskörper in die innere Karte statt in den Konstruktor schreibt. Das Builder-Muster funktioniert in diesem Beispiel wie ein Konstruktor, also ist es nicht meine Absicht, danke trotzdem. – Ivan

Verwandte Themen