0

I am trying to separate item orders and increase the count if the items have same description and variants otherwise adding a new entry in the arraylist.

The original double foreach loop code is as follows which was giving ConcurrentModificationException:

List<OrderedItem> getSortedItems(List<OrderEcomItem> OrderEcomItems, Context context) {
List<OrderedItem> sorted= new ArrayList<>();
for (OrderEcomItem item : OrderEcomItems) {
  final ItemNode itemNode = item.getNodePresentation();
  String variants = "";
  String description = "";
  if (!item.isInStore()) {
    variants = itemNode.formatSelectedItems();
    description = itemNode.getValue().getDescription();
 }

  final int id = item.getMenuItemId();
   if(sorted.size()>0) {
    for (OrderedItem order : sorted) {
      if (order.getMenuItemId() == id) {
       if (order.getVariants().equals(variants)) {
          order.setQuantity(order.getQuantity() + item.getOrderItemQuantity());
          order.setAmount(order.getAmount() + Utils.getSubtotal(item));
        } else {
          sorted.add(
              new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                  Utils.getSubtotal(item),
                  item.getMenuItemId(), variants, description));
        }
      }else {
        sorted.add(
            new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                Utils.getSubtotal(item),
                item.getMenuItemId(), variants, description));
      }
    }
  }else {
      sorted.add(
          new OrderedItem(item.getName(), item.getOrderItemQuantity(),
              Utils.getSubtotal(item),
              item.getMenuItemId(), groups, description));
  }
}
return sorted;

}

With listiterator still it is giving ConcurrentModificationException.

List<OrderedItem> getSortedItems(List<OrderEcomItem> orderEcomItems, Context context) {
List<OrderedItem> sorted= new ArrayList<>();
ListIterator<OrderEcomItem> iterator= orderEcomItems.listIterator();
while (iterator.hasNext()){
  OrderEcomItem item= iterator.next();
  final ItemNode itemNode = item.getNodePresentation();
  String variants = "";
  String description = "";
  String pic = "";
  if (!item.isInStore()) {
    variants = itemNode.selectedItems();
    description = itemNode.getValue().getDescription();
  }

  final int id = item.getEcomItemId();
  if(sorted.size()>0) {
    for (OrderedItem order : sorted) {
      if (order.getEcomItemId() == id) {
        if (order.getVariants().equals(variants)) {
          order.setQuantity(order.getQuantity() + item.getOrderItemQuantity());
          order.setAmount(order.getAmount() + Utils.getSubtotal(item));
        } else {
          sorted.add(
              new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                  Utils.getSubtotal(item),
                  item.getEcomItemId(), variants, description));
        }
      }else {
        sorted.add(
            new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                Utils.getSubtotal(item),
                item.getEcomItemId(), variants, description));
      }
    }
  }else {
    sorted.add(
        new OrderedItem(item.getName(), item.getOrderItemQuantity(),
            Utils.getSubtotal(item),
            item.getEcomItemId(), groups, description));
  }
}
return sorted;


 }

Exception:

java.util.ConcurrentModificationException at java.util.ArrayList$Itr.next(ArrayList.java:831)

Using listIterator on Sorted List

List<OrderedItem> getSortedOrderList(List<OrderEcomItem> orderEcomItems, Context context) {
    List<OrderedItem> sorted= new ArrayList<>();
    ListIterator<OrderedItem> iterator= sorted.listIterator();
    for (OrderEcomItem item : orderEcomItems) {
      final ItemNode itemNode = item.getNodePresentation();
      String variants = "";
      String description = "";
      if (!item.isInStoreItem()) {
        variants = itemNode.selectedItems();
        description = itemNode.getValue().getDesc();
       }

      final int id = item.getEcomItemId();
      if(sorted.size()>0) {
        while (iterator.hasNext()){
          OrderedItem order= iterator.next();
          if (order.getEcomItemId() == id) {
            if (!order.getVariants().isEmpty() && order.getVariants().equals(variants)) {
              order.setQuantity(order.getQuantity() + item.getOrderItemQuantity());
              order.setAmount(order.getAmount() + Utils.getSubtotal(item));
            } else {
              sorted.add(
                  new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                      item.getEcomItemId(), groups, description,
                      item.getExternalId()));
            }
          }else {
            sorted.add(
                new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                    item.getMenuItemId(), groups, description,
                    item.getExternalId());
          }
        }
      }else {
        sorted.add(
            new OrderedItem(item.getName(), item.getOrderItemQuantity(),
                item.getEcomItemId(), variants, description,
                item.getExternalId()));
      }
    }
    return sorted;
  }

}

PS: Please don't mark it duplicate, I have checked list iterator related questions and all of them are using single foreach loop, in my case there are two foreach loops. Kindly provide me solution, where I am doing wrong.

Thanks

Jason
  • 1
  • 1
  • Your code is not modifying the `orderEcomItems` list, so there is no need to use `ListIterator`, just use a `for` loop. --- You *are* modifying the `sorted` list when you call `sorted.add(...)`, and since you're doing it inside a loop, *that* loop needs to use `ListIterator` ***and*** you need to call the [`add(...)`](https://docs.oracle.com/javase/8/docs/api/java/util/ListIterator.html#add-E-) on the `ListIterator`, not on the `List`. – Andreas Apr 05 '21 at 03:41
  • @Andreas I did try that but it was not adding any item and was exiting the loop when it was checking hasNext for sorted list. – Jason Apr 05 '21 at 03:45
  • *"it was not adding any item"* If you call `add(...)`, then an element *will* be added, so that isn't true. --- *"was exiting the loop when it was checking hasNext"* Well, it is supposed to exit the loop when it gets to the end of the elements in the loop. Note that the iteration will not see the newly added elements. Did you read the documentation for the `ListIterator.add(...)` method to see where a new element is being added? – Andreas Apr 05 '21 at 03:49
  • @Andreas I have edited the question please check the last part of the code and could you please tell me where I am doing wrong. Its not adding items in the list after one item. – Jason Apr 05 '21 at 03:56
  • Try creating the iterator right before the `while` loop, not outside the `for` loop. As-is, on second (and third and ...) iteration of the `for` loop, the iterator is already at-end, so the `while` loop will be skipped. --- It's ok to use Homer Simpsons catchphrase at this time: [*DOH!*](https://youtu.be/cnaeIAEp2pU) – Andreas Apr 05 '21 at 04:23
  • @Andreas I did try that, it did not work. Crashing after 2-3 entries – Jason Apr 05 '21 at 04:47
  • Since we don't know the code that crashed, and since "crashed" doesn't say anything informative, we can't really do anything about that. I mean, the code in the question is still not using the `add()` method in the iterator, even though you were told to use that long ago (in the previous version of this re-created question, I believe). – Andreas Apr 05 '21 at 04:52
  • The fact that there are two foreach loops is irrelevant. The fact that you're adding to a list as you iterate over that list is the problem. The duplicate is correct. – Ryan M May 11 '21 at 05:18

1 Answers1

0

I think your problem is this line:

sorted.add(...)

inside the loop where you are iterating over sorted list. You are iterating over the elements in sorted array and within the loop you are adding new elements to the list. This will throw ConcurrentModificationException. I'd suggest add them to a separate list.

Rafay
  • 92
  • 8
  • should I take one more list? I am already taking a separate list to separate items. – Jason Apr 05 '21 at 03:37
  • Its hard to read your code because the formatting is not good. I am not sure about the context of your problem, but what i understood is that for every element in orderEcomItems, you first decide if it can be added to sorted list, and the next time, you iterate the sorted list and while iterating, you add more elements to it (this part is the problem). You should just add them into a temporary array and at the end of your iteration for orderEcomItems, add all the elements from the temporary array to the sorted array. – Rafay Apr 05 '21 at 03:44
  • I am preparing an ecommerce app and getting list of items ordered. I want to show if the items and their variants are same then it should increase the count and If the variant is different even if the item id is same it should show separate item in the list. – Jason Apr 05 '21 at 03:50