Reputation: 2952
Given a List of Foo myFoos, I need to map those to a collection of a different class, say Bar. I do it like this now:
List<Bar> myBars = new...
for(Foo f : foos) {
Bar b = new Bar();
b.setAProperty(f.getProperty);
b.setAnotherProp(f.getAnotherProp);
myBars.add(b);
}
So, is there an easier way to do this? Granted this is pretty easy, but I'm wondering if there's any magic out there that would morph the foos to bars without having to manually walk the list, particularly because my input list can be big.
If not, do you guys know if the compiler does anything to optimize this? I'm worried mainly about performance.
Thanks!
--
Llappall
Upvotes: 3
Views: 170
Reputation: 431
Another idea, which is - granted - approriate in very rare cases only.
Implement (kind of) a Fyweight pattern
Prerequisite: The set of properties of Foo
and Bar
is the same.
Foo
and Bar
into an external class, say Properties
. Properties
for Foo and Bar.Bar
and want to initialize it from Foo
, just pass the Properties from the Foo
instance to the new Bar
instance.Pros:
Cons:
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
}
Upvotes: 0
Reputation: 431
One idea which is not a general solution, but could be appropriate in some situations:
Pull the properties
Instead of pushing the properties from Foo to Bar whenever a Bar is instantiated, just associate a Foo to a new Bar and map the properties in the property 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(); } }
This does not prevent you from looping over Foos to instantiate Bars. But it delays the effort to map properties.
Upvotes: 0
Reputation: 2123
public Bar(Foo f){
this.a = f.a;
this.b = f.b;
}
for (Foo f : myFoos){
myBars.add(new Bar(f));
}
Upvotes: 2
Reputation: 272507
You can't really avoid walking the list, because you have to convert every item!
But you can simplify your syntax if you write a Bar
constructor that takes a Foo
. Then your loop can become:
for(foo f : foos) {
myBars.add(new Bar(f));
}
Depending on your scenario, an alternative is to not create the list of Bar
s at all. Instead, you can simply add a Foo.getAsBar()
method, so that you dynamically generate a Bar
object as required. If the number of elements in the container is higher than the total number of times that you'll need to access them, then this may be more efficient.
Upvotes: 7