I have a java application which uses JPA.
Say I have an entity called Product
with name
and price
attributes (all entities have an id
attribute).
Naturally I can get a List<Product>
fairly easily (from a query or another entity), but often I want a List<String>
(list of product names) or List<Long>
(list of product prices or list of product ids).
A lot of the time it's just as easy to pass the whole Product
around, but there are two cases where I don't want to do this:
- I'm passing the list to a class which shouldn't have a dependency on the
Product
class. - It's significantly easier/faster to get a list of ids than full product objects, (but in some cases I already have them).
The naive way to do this would go something like:
List<Long> productIds = new ArrayList<Long>();
for(Product product: products) {
productIds.add(product.getId());
}
But I don't like this because it's messy and inefficient. In python I would do something like:
[ p.id for p in products ]
The "best" I can come up with in Java is:
public class ProductIdList extends AbstractList<Long> {
private List<Product> data;
public ProductIdList(List<Product> data) {
this.data = data;
}
public Long get(int i) {
return data.get(i).getId();
}
public int size() {
return data.size();
}
public Long remove(int i) {
return data.remove(i).getId();
}
/* For better performance */
public void clear() {
data.clear();
}
/* Other operations unsupported */
}
Pros:
- This approach doesn't need to copy the data
- It is a true "view" on the data - changes to the underlying list are reflected.
Cons:
- Seems like a lot of code
- Need a class like this for each attribute I want to access like this
So is this a good idea or not? Should I just be creating secondary lists most of the time? Is there a third option I haven't considered?