如何在异构List中查找给定类型的对象

时间:2009-12-24 19:44:46

标签: java generics

我有一个异构List,可以包含任意类型的对象。我需要找到一个特定类型的List元素。通过查看其他泛型相关问题的答案,我找不到我需要的内容。

这是我想要完成的一个例子:

List <Object> list = new ArrayList <Object>(); 

...

private someMethod() {
   Customer cust = findInList( Customer.class );
   Invoice inv = findInList( Invoice.class );
}

那么,如何使用泛型定义findInList?我认为类型擦除会导致问题,我不太了解这个问题,但我不想定义多个“查找”方法,因为列表中可能存在数十种不同类型的对象。

2 个答案:

答案 0 :(得分:9)

您可以使用Josh Bloch描述的Typesafe异构容器模式。以下是Josh演讲的一个例子:

class Favorites {
    private Map<Class<?>, Object> favorites =
            new HashMap<Class<?>, Object>();

    public <T> void setFavorite(Class<T> klass, T thing) {
        favorites.put(klass, thing);
    }

    public <T> T getFavorite(Class<T> klass) {
        return klass.cast(favorites.get(klass));
    }

    public static void main(String[] args) {
        Favorites f = new Favorites();
        f.setFavorite(String.class, "Java");
        f.setFavorite(Integer.class, 0xcafebabe);
        String s = f.getFavorite(String.class);
        int i = f.getFavorite(Integer.class);
    }
}

您可以轻松地将其扩展为支持每种类型的收藏列表,而不是单个值。

答案 1 :(得分:5)

您可以使用[Class.isInstance()](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#isInstance(java.lang.Object))和[Class.cast()](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#cast(java.lang.Object))方法定义方法。这是一个示例实现(列表的附加参数) ):

static <T> T findInList(List<?> list, Class<T> clazz) {
  for (Object o : list) {
    if (clazz.isInstance(o)) {
      return clazz.cast(o);
    }
  }
  return null;
}

更新:我建议不要在Collection中添加多种类型。这通常表示需要自定义数据类型(例如Transaction)或元组值。