Reputation: 161
These are classes of my project. The class Bean is a super type of Employe and Computer and not is intanziable.
abstract Class Bean{
private HashMap<String, String> fields = null;
protected Bean(Map<String, Object> row) {
//fill HashMap fields
}
}
public class Employe extends Bean {
public Employe (Map<String, Object> row) {
super(row);
}
}
public class Computer extends Bean {
public Computer (Map<String, Object> row) {
super(row);
}
}
How to make it more generic this for loop with generics ?
I would write the two cycles below once using generics in a utility method riusable.
//Loop 1
List<Map<String, Object>> employeRows = //from query on database
List<Employe> employList = new ArrayList<Employe>();
for (Map<String, Object> row : employeRows) {
Employe e = new Employe(row);
employList .add(e);
}
//Loop 2
List<Map<String, Object>> computerRows = //from query on database
List<Computer> computerList = new ArrayList<Computer>();
for (Map<String, Object> row : computerRows ) {
Computer c = new Computer(row);
computerList.add(c);
}
This pseudo-code is an example of what I want to achieve:
List<Employe> = Utility.toList(employeRows, ...);
List<Computer> = Utility.toList(computerList, ...);
Upvotes: 3
Views: 663
Reputation: 213223
If you're using Java 7 or below, factory pattern is the way to go. But if you're already on Java 8, you can achieve this with streams and lambda / method reference.
Here's how you do it with Java 8:
public static <T> List<T> toList(List<Map<String, Object>> rows, Function<Map<String, Object>, T> mapper) {
return rows.stream().map(mapper).collect(Collectors.toList());
}
And then call this method by passing the constructor as method reference:
List<Map<String, Object>> employeRows = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> computerRows = new ArrayList<Map<String, Object>>();
List<Employe> employList = toList(employeRows, Employe::new);
List<Computer> computerList = toList(computerRows, Computer::new);
Upvotes: 4
Reputation: 8075
Use a Factory Pattern, one abstract factory
interface ObjectCreater<T> {
T create(Map<String, Object> row);
}
and two Implementations, e.g. for Employee
class EmployeeCreater implements ObjectCreator<T> {
T create(Map<String, Object> row) {
return new Employee(row); // or the constructor logic inlined
}
}
define a method (= Utility.toList()):
List<T> toList(List<Map<String, Object>> row, ObjectCreator<T> creator) {
// the upper loop using the factory instead of the Constructor
}
Upvotes: 1