简体   繁体   中英

Java for loop executed twice

I am experiencing some troubles when executing a for loop. The loop is called twice. Here is the code that does the work:

import java.util.ArrayList;
import java.util.List;

public class PoolItemMapper {
    public  List<Item> mapJsonObjectsToItems(JsonResponse jsonResponse) {
        int count = 0;
        List<Item> itemsList = new ArrayList<>();
         List<Item> js = jsonResponse.getItems();
        for (Item item : jsonResponse.getItems()) {
            itemsList.add(addNormalItemProperties(item, new Item()));
            count++;
        }
        System.out.println("Call count: " + count);
        return itemsList;
    }

    private  Item addNormalItemProperties(Item oldItem, Item newItem) {
        if(oldItem.getMembersReference().getItems().size() <=  0) {
            return oldItem;
        } else if (oldItem.getMembersReference().getItems().size() > 0) {
            for (SubItem subItem: oldItem.getMembersReference().getItems()) {
                oldItem.getSubItems().add(creteNewSubItem(subItem));
            }
        }
        return oldItem;
    }

    private  Item creteNewSubItem(SubItem oldItem) {
        Item i = new Item();
        i.setDynamicRatio(oldItem.getDynamicRatio());
        i.setEphermal(oldItem.getEphermal());
        i.setInheritProfile(oldItem.getInheritProfile());
        i.setLogging(oldItem.getLogging());
        i.setRateLimit(oldItem.getRateLimit());
        i.setRatio(oldItem.getRatio());
        i.setSession(oldItem.getSession());
        i.setAddress(oldItem.getAddress());
        i.setName(oldItem.getName());
        i.setState(oldItem.getState());

        return i;
    }

}

The list has a size of 134, so I receive an output of two times 'Call count 134'. This results in having duplicates in the list.
Here are the POJOs:

JSON response where getItems() for the foor loop is called:

public class JsonResponse {
    private String kind;
    private String selfLink;
    private List<Item> items = new ArrayList<Item>();

    public JsonResponse() {

    }

    public String getKind() {
        return kind;
    }

    public void setKind(String kind) {
        this.kind = kind;
    }

    public String getSelfLink() {
        return selfLink;
    }

    public void setSelfLink(String selfLink) {
        this.selfLink = selfLink;
    }

    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }
}

The Item class is a simple DTO, containing only variables and their getters/setters:
Here is where the method is invoked:

itemTree = new PoolTreeBuilderImpl().buildTree(j);

itemTree.stream().forEach(i -> {
    System.out.println("[PARENT] " + i.getData().toString());
    i.getData().getSubItems().stream().forEach(si -> {
        System.out.println("       [CHILD] " + si.toString());
    });
});

}

and the PoolTreeBuilderImpl calls:

@Override
public List<TreeNode<Item>> buildTree(JsonResponse jsonResponse) {
    List<TreeNode<Item>> itemTree = new ArrayList<>();
    List<Item> mappedItems = new PoolItemMapper().mapJsonObjectsToItems(jsonResponse);
    for (Item i : mappedItems) {
        TreeNode<Item> item = new TreeNode<>(i);
        if (i.getSubItems().size() > 0) {
            for (Item subItem : i.getSubItems()) {
                item.addChild(subItem);
            }
        }
        itemTree.add(item);
    }
    return itemTree;
}

Could someone explain me why this loop is called twice resulting in having each subitem twice in the list?

Update
When executing this code, I don't have the duplicates:

List<Item> mappedItems = new PoolItemMapper().mapJsonObjectsToItems(jsonResponse);
mappedItems.forEach(i -> {
    System.out.println("[PARENT] " + i.toString());
    i.getMembersReference().getItems().forEach(s -> {
        System.out.println("      [CHILD] " + s.toString());
    });
});

The problem lies in the JsonResponse object, which is always the same. The objects within the JsonResponse list are modified twice, so there are duplicates. That is why (@Joakim Danielson) there is the second parameter newItem .
Additionally I had to change the signature of the buildTree method of the TreeBuilder to accept a list of Item s, the one returned by the mapper.

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