Get generic type of java.util.List

后端 未结 14 2297
广开言路
广开言路 2020-11-22 02:06

I have;

List stringList = new ArrayList();
List integerList = new ArrayList();

Is

14条回答
  •  迷失自我
    2020-11-22 02:29

    The generic type of a collection should only matter if it actually has objects in it, right? So isn't it easier to just do:

    Collection myCollection = getUnknownCollectionFromSomewhere();
    Class genericClass = null;
    Iterator it = myCollection.iterator();
    if (it.hasNext()){
        genericClass = it.next().getClass();
    }
    if (genericClass != null) { //do whatever we needed to know the type for
    

    There's no such thing as a generic type in runtime, but the objects inside at runtime are guaranteed to be the same type as the declared generic, so it's easy enough just to test the item's class before we process it.

    Another thing you can do is simply process the list to get members that are the right type, ignoring others (or processing them differently).

    Map, List> classObjectMap = myCollection.stream()
        .filter(Objects::nonNull)
        .collect(Collectors.groupingBy(Object::getClass));
    
    // Process the list of the correct class, and/or handle objects of incorrect
    // class (throw exceptions, etc). You may need to group subclasses by
    // filtering the keys. For instance:
    
    List numbers = classObjectMap.entrySet().stream()
            .filter(e->Number.class.isAssignableFrom(e.getKey()))
            .flatMap(e->e.getValue().stream())
            .map(Number.class::cast)
            .collect(Collectors.toList());
    
    
    

    This will give you a list of all items whose classes were subclasses of Number which you can then process as you need. The rest of the items were filtered out into other lists. Because they're in the map, you can process them as desired, or ignore them.

    If you want to ignore items of other classes altogether, it becomes much simpler:

    List numbers = myCollection.stream()
        .filter(Number.class::isInstance)
        .map(Number.class::cast)
        .collect(Collectors.toList());
    

    You can even create a utility method to insure that a list contains ONLY those items matching a specific class:

    public  List getTypeSafeItemList(Collection input, Class cls) {
        return input.stream()
                .filter(cls::isInstance)
                .map(cls::cast)
                .collect(Collectors.toList());
    }
    
        

    提交回复
    热议问题