简体   繁体   中英

Get specific class objects from HashSet in Java

I have a public Set<ProjectItem> projectItems = new HashSet<ProjectItem>(); which can contains two types of classes ( ProjectItem is a abstract super class for both of them). The classes are Deliverable and Task . I want get all objects of the class Deliverable from the Set . Therefore I write this:

public Set<Deliverable> allDeliverables(){
Set<Deliverable> result = new HashSet<Deliverable>();
for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()){
    if (iter.next().getClass() == Deliverable.class){
    Deliverable del = (Deliverable) iter.next();
    result.add(del);
    }
}
return result;
}

But this makes an exception -

Exception in thread "main" java.lang.ClassCastException: edu.Chryb.ProjectManagement.Task cannot be cast to edu.Chryb.ProjectManagement.Deliverable

in the Line with: Deliverable del = (Deliverable) iter.next();

Is something in the if query wrong?

Thanks for every help.

Your code is a bit out. Try:

for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()){
    ProjectItem item = iter.next();
    if (item.getClass() == Deliverable.class){
        result.add((Deliverable)item);
    }
}

The problem is the multiple invocations of iter.next() (because it return current element and forwards the cursor to the next element) within the loop.

Within the loop do something as follows first -

for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext();){
    ProjectItem currItem = iter.next();
    //...

And then use currItem instead of calling iter.next() multiple times.


Side Note:

for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()) {

The call iter.next() doesn't have to do with the mentioned problem but it shouldn't be there also. Because that you will skip actual current element.

You are calling iter.next() twice - once in the check, and once on the retrieval. It appears that you find a Deliverable followed by Task . The check of Deliverable succeeds, but the iterator moves on to Task right after that, so the following invocation of next returns a Task , not a Deliverable .

Change your code as follows:

for(Iterator<ProjectItem> iter = projectItems.iterator(); iter.hasNext(); iter.next()){
    ProjectItem next = iter.next();
    if (next.getClass() == Deliverable.class){
        Deliverable del = (Deliverable) next;
        result.add(del);
    }
}

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