开发者

How to find object of given type in a heterogeneous List

开发者 https://www.devze.com 2022-12-14 16:25 出处:网络
I have a heterogeneous List that can contain any arbitrary type of object. I have a need to find an element of the List that is of a certain type. Looking through the answers of other generics related

I have a heterogeneous List that can contain any arbitrary type of object. I have a need to find an element of the List that is of a certain type. Looking through the answers of other generics related questions, I'm not finding exactly what I need.

Here's an example of what I'm trying to accomplish:

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

...

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

So, how do I def开发者_StackOverflow社区ine findInList using generics? I gather that type erasure causes issues here and I don't know as much about that as I probably should, but I'd rather not define multiple "find" methods since there could be dozens of different types of objects living in the List.


You can use Typesafe Heterogeneous Container pattern described by Josh Bloch. Here is an example from Josh's presentation:

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);
    }
}

You can easily extend this to support List of favorites per type instead of a single value.


You can define the method using [Class.isInstance()](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#isInstance(java.lang.Object)) and [Class.cast()](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#cast(java.lang.Object)) method. Here is a sample implementation (with extra argument for the list):

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

Update: I would recommend against putting multiple types in the Collection. It's usually a sign that either need a custom datatype (e.g. Transaction) or a Tuple value.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号