首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有效地处理List<Entity>、List<Entity Id>、List<Entity name>?

如何有效地处理List<Entity>、List<Entity Id>、List<Entity name>?
EN

Stack Overflow用户
提问于 2009-09-30 12:07:40
回答 3查看 10K关注 0票数 2

我有一个使用JPA的java应用程序。

假设我有一个名为Product的实体,它具有nameprice属性(所有实体都有id属性)。

当然,我可以很容易地获得一个List<Product> (来自查询或其他实体),但我通常需要一个List<String> (产品名称列表)或List<Long> (产品价格列表或产品I列表)。

很多时候,传递整个Product也同样容易,但是有两种情况我不想这样做:

  • 我将列表传递给一个不应该依赖于Product类的类。
  • 获得in列表比获得完整的产品对象要容易/快得多(但在某些情况下,我已经拥有了它们)。

这样做的天真方式可能是这样的:

代码语言:javascript
复制
List<Long> productIds = new ArrayList<Long>();
for(Product product: products) {
  productIds.add(product.getId());
}

但我不喜欢这样,因为它杂乱无章,效率低下。在python中,我会这样做:

代码语言:javascript
复制
[ p.id for p in products ]

我在Java中所能想到的“最好的”是:

代码语言:javascript
复制
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 */
}

优点:

  • 这种方法不需要复制data
  • ,它是数据上的一个真正的“视图”--反映了对底层列表的更改。

缺点:

  • 似乎很多代码
  • 都需要这样一个类,对于我想要访问的每个属性,比如

这到底是个好主意还是不好?我应该大部分时间都在创建次要列表吗?还有第三种我没有考虑过的选择吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-09-30 14:51:23

通过让每个属性包装器类从具有getAttribute方法的抽象类继承,可以最小化这些类的大小。就像这样:

代码语言:javascript
复制
public abstract class AbstractProductList<T> extends AbstractList<T> {
  protected List<Product> data;

  public AbstractProductList(List<Product> data) {
    this.data = data;
  }

  protected abstract T getAttribute(Product product);

  public T get(int i) {
    return getAttribute(data.get(i));
  }

  public int size() {
    return data.size();
  }

  public T remove(int i) {
    return getAttribute(data.remove(i));
  }

  /* For better performance */
  public void clear() {
    data.clear();
  }

  /* Other operations unsupported */
}

public class ProductIdList extends AbstractProductList<Long> {
  public ProductIdList(List<Product> data) {
    super(data);
  }

  protected Long getAttribute(Product product) {
    return product.getId();
  }
}
票数 2
EN

Stack Overflow用户

发布于 2009-09-30 15:40:50

为了提供另一种可能性,您可以使用Apache Commons和collection创建一个新的集合或转换来修改现有的集合:

代码语言:javascript
复制
  Collection<Long> productIds = CollectionUtils.collect(products, new Transformer() {
      public Long transform(Object o) {
          return ((Product) o).id;
      }
  });
票数 3
EN

Stack Overflow用户

发布于 2009-09-30 14:48:51

您可以使用一个对每个属性都有一个方法的类。这至少可以减少一个缺点。

这是你的例子,与我的建议调整。

代码语言:javascript
复制
public class ProductList {
  private List<Product> data;

  public ProductIdList(List<Product> data) {
    this.data = data;
  }

  public Long getId(int i) {
    return data.get(i).getId();
  }

  public List<String> getProductNames(int i) {
    return data.get(i).getProductNames();
  }

  public Product getProduct(int i) {
    return data.get(i);
  }

  public int size() {
    return data.size();
  }

  public Long remove(int i) {
    return data.remove(i).getId();
  }

  /* For better performance */
  public void clear() {
    data.clear();
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1497712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档