プロパティDeveloperのリストAがあります。開発者のスキーマはそれが好きです:
@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を使用して、上記をよりエレガントで簡潔な方法でどのように書くことができますか?
以下のようなものを使用する必要があります:
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);
おそらく、このように:
List<ProductManager> B = A.stream()
.map(developer -> new ProductManager(developer.name, developer.age))
.collect(Collectors.toList());
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());
ProductMangerにbelwoコンストラクターを追加しても問題ない場合
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);
それ以外の場合は、カスタムマッパーを提供できます
Function<Developer, ProductManager> mapper = d -> new ProductManager(d.getName(), d.getAge());
これをmap
関数で使用します
出力
[ProductManager [name=abc, age=25]]