简体   繁体   中英

How do I addAll() items from a JAXB-generated collection to a simple ArrayList?

I'm trying to use JAXB to pull some elements from a large XML file (technically, it's XTCE .)

JAXB generated a collection of objects for me. To get the subset of desired elements, I need to call:

List<SequenceEntryType> org.omg.space.xtce.EntryListType.getParameterRefEntryOrParameterSegmentRefEntryOrContainerRefEntry();

I'd like to fill up an

ArrayList<ParameterRefEntryType> integerParameters;

with the return value using the following code:

integerParameters.addAll(...); // calling long JAXB-generated function above

The ParameterRefEntryType derives from SequenceEntryType , so this should be kosher as long as I used an appropriate cast.

However, Eclipse reports:

"The method addAll(Collection < ? extends ParameterRefEntryType>) in the type ArrayList is not applicable for the arguments (ParameterRefEntryType)."

I'm rusty on Java generic Collections, and I don't fully understand what's going on here. It seems like I need to redefine my ArrayList to only accept items of type ParameterRefEntryType. Can I use addAll() like this, or do I need to write my own loop to add the desired elements?

The alternative seems to be:

List<SequenceEntryType> entries = 
    entryList.getParameterRefEntryOrParameterSegmentRefEntryOrContainerRefEntry();
Iterator<SequenceEntryType> entryIterator = entries.iterator();
while (entryIterator.hasNext()) {
    SequenceEntryType currEntry = entryIterator.next();
    if (currEntry instanceof ParameterRefEntryType) {
        _integers.add(currEntry);
    }
}

If this method is necessary, I'll definitely consider using lambdaj .

I can't give you hints about JAXB but this is a bit about collections:

You have:

1. ParameterRefEntryType extends SequenceEntryType
2. ArrayList<ParameterRefEntryType> integerParameters;

and now look at definiitions add and addAll:

public boolean addAll(Collection<? extends E> c)
public boolean add(E e)

In your case E is ParameterRefEntryType

so integerParameters.addAll() can work only with ? extends ParameterRefEntryType it's mean that you can put there only elements ParameterRefEntryType and childrens

add() has similar requirement so if you want add this object you can do this manually, but you must cast your currEntry:

integerParameters.add((ParameterRefEntryType) currEntry);

Your loop can be written a bit shorter:

for(SequenceEntryType currEntry :
     entryList.getParameterRefEntryOrParameterSegmentRefEntryOrContainerRefEntry()) {

    if (currEntry instanceof ParameterRefEntryType) {
        _integers.add((ParameterRefEntryType)currEntry);
    }
}

Of course, it looks better if your method names are not so absurdly long.

smas already said why it does not work with addAll (the original list can contain elements which are not of type ParameterRefEntryType).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM