【问题标题】:How do I get contents of collections with generics?如何使用泛型获取集合的内容?
【发布时间】:2011-03-13 11:55:54
【问题描述】:

我从休眠查询中获取对象。然后我有字段列表,我必须在这个对象上调用它们的吸气剂。因此,在我调用这些 getter(不取决于我,所以我不知道它们返回什么)之后,我将这些对象放在一个数组 Object[] 中。现在我正在遍历这些对象,其中一些又是包含其他对象的集合。 所以我检查对象是否是这样的集合

private static boolean isCollection(Object obj){
    Class clazz = obj.getClass();
    return Collection.class.isAssignableFrom(clazz) ||     
     Map.class.isAssignableFrom(clazz);
}

现在我需要做一些类似的事情:

 if(isCollection(object)){
       get subobjects from this collection();
       getDeclaredMethods of this type of object();
       do something with everyObject();
}

感谢有关如何使其通用的所有帮助。哦,是的,这个方法是检查一个地图,但在我的情况下,一般来说,地图不能返回,只能返回集合和列表。

谢谢

编辑:如果不清楚,我将在此处添加确切的代码以供参考

Object[] objectRow = parseObject(hibernateObject);
for(Object field: objectRow){
      get subobjects from this collection();
   getDeclaredMethods of this type of object();
   do something with everyObject();

}

public Object[] parseObject(Object mainObject) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
    rowToReturn = new Object[fieldObjects.size()];

    Method[] allMethods = mainObject.getClass().getMethods();
    Method[] getters = findGetters(allMethods);
    cutGetters(getters); // builds map so that we match getters with fields



    for(FieldObject field: fieldObjects){
        if(getterNameMethodMap.containsKey(field.getFinalFieldName())){
            Method methodToInvoke = getterNameMethodMap.get(field.getFinalFieldName());

            Object invokedObject = methodToInvoke.invoke(mainObject, (Object) null);
            rowToReturn[field.getOrder()] = invokedObject; // put what ever it is that we got, into the final array
        }
    }

    return rowToReturn;
}


private void cutGetters(Method[] getters){
    getterNameMethodMap = new HashMap<String, Method>();
    for(Method getter:getters){
        String stringToGet = getter.getName().substring(4,getter.getName().length());
        getterNameMethodMap.put(stringToGet, getter);
    }

【问题讨论】:

  • 你真的需要一个包含“非集合”对象和其他集合的集合吗?拥有一个包含来自不同类层次结构的对象的集合很少是一个好的决定。
  • @stoupa:我正在从休眠查询中获取一个对象。在那个对象上,我必须调用一些 getter 方法,无论它们返回什么,我都必须放在这个列表中......目前我不知道如何将它们分开,因为我永远不知道我会得到什么,可以是任何东西: /
  • @Julia:如果我理解正确,您将从不同的 getter 方法(具有不同的返回类型)返回的结果添加到上面提到的一个集合中。对吗?
  • @stoupa 是的。我从休眠查询中获取对象。然后我有字段列表,我必须调用它们的吸气剂。所以在我调用这些getter(不取决于我,所以我不知道它们返回什么)之后,我将这些对象放在一个列表中。然后我必须做我上面解释过的我必须做的事情:)
  • @Julia:您能否发布您正在描述的代码部分?

标签: java generics collections


【解决方案1】:

这正是泛型试图阻止的代码。泛型试图承担在您的代码中分散if object.type == class 的负担。看看这里,这只是一个介绍:

http://en.wikipedia.org/wiki/Generics_in_Java

因为你有一个集合的集合对象,你会做这样的事情:

List<List<? extends Shape>>

这是为了声明一个列表的列表,并且尽可能准确地说明这些内部列表包含哪种对象(我选择 Shape 只是作为示例,不知道您要处理哪种对象)。您可以在此处找到该确切代码的解释:

http://download.oracle.com/javase/tutorial/extra/generics/methods.html

【讨论】:

  • 我没有集合,我有对象集合。其中一些对象是集合(我是这样写的:)),一些是字符串,一些是第三个对象。所以列表> 不能在我的列表中定义。
  • 这很不寻常。也许您可以更改生成此集合的方法?例如而不是 list{list,string,list,string} 到这个:list{list{},list{string},list{},list{string}}。如果您想迭代,这会好得多...
  • 你可以看一下,我编辑了我的原始帖子来解释我如何得到这个不同对象的初始列表。谢谢你的回复。
【解决方案2】:

因为泛型在编译时被删除,根据定义,如果您在编译时不知道该类型,则它们不能用于确定对象的类型。不幸的是,在不更改任何代码的情况下为您提供可能是也可能不是集合的对象数组,确定它们的类型的唯一方法是像您已经在做的那样手动检查返回的对象的类型。

更多信息:http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

P.S.:这并不是说没有更有效的方法来做你正在做的事情。通过强制转换那些您已经确定为集合的对象,您可以“做某事”而无需借助反射来获取声明的方法。然而,实际的确定不能用泛型来捷径。

【讨论】:

    猜你喜欢
    • 2020-03-07
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    相关资源
    最近更新 更多