给定一个Foo myFoos列表,我需要将它们映射到另一个类的集合,比如Bar。我现在这样做:
List<Bar> myBars = new...
for(Foo f : foos) {
Bar b = new Bar();
b.setAProperty(f.getProperty);
b.setAnotherProp(f.getAnotherProp);
myBars.add(b);
}
那么,有没有更简单的方法呢?这很简单,但我想知道是否有任何魔法可以将foos变形为条形而不必手动遍历列表,特别是因为我的输入列表可能很大。
如果没有,你们知道编译器是否做了什么来优化它?我主要担心的是表现。
谢谢!
-
Llappall
答案 0 :(得分:7)
你无法真正避免走在列表中,因为你必须转换每个项目!
但是,如果编写一个Bar
构造函数来获取Foo
,则可以简化语法。然后你的循环可以变成:
for(foo f : foos) {
myBars.add(new Bar(f));
}
根据您的情况,另一种方法是根本不创建Bar
列表。相反,您只需添加Foo.getAsBar()
方法,以便根据需要动态生成Bar
对象。如果容器中的元素数量高于您需要访问它们的总次数,那么这可能会更有效。
答案 1 :(得分:2)
public Bar(Foo f){
this.a = f.a;
this.b = f.b;
}
for (Foo f : myFoos){
myBars.add(new Bar(f));
}
答案 2 :(得分:0)
一个想法不是一般解决方案,但在某些情况下可能是适当的:
拉出属性
只要在实例化Bar时,不要将属性从Foo推送到Bar,只需将Foo关联到新的Bar并在属性getters中映射属性。
public class Bar {
Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public int getPropertyA() {
return foo.getPropertyA();
}
public int getAnotherProperty() {
return foo.getAnotherProperty();
}
}
public class Bar {
Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public int getPropertyA() {
return foo.getPropertyA();
}
public int getAnotherProperty() {
return foo.getAnotherProperty();
}
}
这不会阻止您循环使用Foos来实例化Bars。但它延迟了地图属性的努力。
答案 3 :(得分:0)
另一个想法 - 被授予 - 仅在极少数情况下适用。
实施(种类)Fyweight pattern
先决条件:Foo
和Bar
的属性集相同。
Foo
和Bar
的常用属性放入外部类,例如Properties
。 Properties
类型的属性。Bar
的新实例并想要从Foo
初始化它时,只需将属性从Foo
实例传递到新的Bar
实例。 / LI>
优点:
缺点:
public class Properties {
public int getPropertyA() {..}
public int getAnotherProperty() {..}
}
public class Foo {
Properties properties;
public Foo(Properties properties)
this.properties = properties;
}
public Properties getProperties() {
return properties;
}
}
public class Bar {
Properties properties;
public Foo(Properties properties)
this.properties = properties;
}
public Properties getProperties() {
return properties;
}
}
//Client code:
//Access properties:
int i = foo.getProperties().getPropertyA();
//Map Foos to Bars
for (Foo foo: foos) {
Bar bar = new Bar(foo.getProperties());
//Do something with bar
}