2016-10-14 22 views
3

有一個名單A與財產開發商。開發架構喜歡那樣:如何將具有屬性的列表轉換爲另一個列表java 8的方式?

@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; 
    } 
} 

與性能列表A:

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

它需要轉換列表A到列表B與財產ProductManager和性質是一樣的列表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; 
    } 
} 

在過去,我們會寫出這樣的代碼:

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; 
} 

我們如何使用Java 8以更優雅簡潔的方式編寫上述代碼?

+3

這裏真正的問題是,爲什麼'Developer'和'ProductManager'不似乎從一個封裝了'name'和'age'的公共超類'Person'繼承。在你升級到漂亮的Java8鈴聲和哨聲之前,你應該可以讓設計正確。 –

+0

@JimGarrison是的,我同意你的看法,我需要更多地關注基本面。如果有更多的屬性,也許超過20,並且構造函數不能直接使用,如何轉換? – Ivan

+1

如果'Developer'和'ProductManager'有一個共同的基類Person,定義了所有公共屬性,那麼在兩個類中定義一個帶有Person參數的構造函數都沒有問題。這些構造函數只會委託給執行這個工作的'Person'基類的構造函數,所以它只能被實現一次。請注意,這是一種已建立的模式,即所有標準的'Collection'類型都提供了一個構造函數來接受要從中複製的'Collection'參數。 – Holger

回答

4

你將不得不使用類似如下://爲

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

大#假設性的屬性也有類似的名稱 //其他明智的名稱請參考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

如果有更多的屬性,可能超過20,並且構造函數不能直接使用,如何轉換? – Ivan

+1

@Ivan用PropertyUtils添加了一個示例,似乎是一個簡單的方法來做到這一點 –

0

也許,就像這樣:

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

如果你細加belwo構造函數ProductManger

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

然後利用構造參考

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

否則你可以提供轉換自定義映射器

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

使用本

輸出

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

如果有更多的屬性,也許超過20,並且構造函數不能直接使用,如何轉換? – Ivan

+0

在上面的mapper函數中,不是使用構造函數,而是創建一個產品管理器對象,設置它的所有屬性並將其返回 – Saravana

0

如果有更多的屬性,也許超過20個,並構造 不能直接使用,如何轉換?

如果您有任何超過3-4屬性來設置,你應該使用生成器,像這樣:

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

您的意思是使用構建模式?這是正確的。我的問題是如何在內部映射中寫入函數體,而不是構造函數。這個示例中的構建器模式的構造函數的工作原理,所以它不是我的意圖,無論如何。 – Ivan

相關問題