我有一个使用 JPA 的 java 应用程序。
假设我有一个名为 Product
的实体与 name
和 price
属性(所有实体都有一个 id
属性)。
自然我可以得到一个List<Product>
相当容易(来自查询或另一个实体),但通常我想要一个 List<String>
(产品名称列表)或 List<Long>
(产品价格列表或产品 ID 列表)。
很多时候通过整个 Product
也很容易周围,但有两种情况我不想这样做:
- 我正在将列表传递给不应依赖于
Product
的类类。 - 获取 ID 列表比获取完整的产品对象更容易/更快,(但在某些情况下我已经有了它们)。
最简单的做法是:
List<Long> productIds = new ArrayList<Long>();
for(Product product: products) {
productIds.add(product.getId());
}
但我不喜欢这样,因为它凌乱且效率低下。在 python 中,我会做类似的事情:
[ p.id for p in products ]
我能想到的 Java 中的“最佳”是:
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 */
}
优点:
- 这种方法不需要复制数据
- 它是对数据的真实“ View ”- 反射(reflect)了对基础列表的更改。
缺点:
- 似乎有很多代码
- 我想像这样访问的每个属性都需要一个这样的类
那么这是个好主意吗?大多数时候我应该只创建二级列表吗?有没有我没有考虑过的第三种选择?
最佳答案
只是抛出另一种可能性,您可以使用 Apache Commons 的 Transformer 和 collect 来创建新集合或转换以修改现有集合:
Collection<Long> productIds = CollectionUtils.collect(products, new Transformer() {
public Long transform(Object o) {
return ((Product) o).id;
}
});
关于java - 如何最好地有效处理 List<Entity>、List<Entity Id>、List<Entity name>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1497712/