Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I perform a conditional check in a double loop efficiently?

I didn't really know how to formulate the title of this question, so I'll just jump into an example.

Let's say that I want to iterate over a list of elements, and based on certain conditions, add said element to a new list.

Here I create a method that basically wants to check if an item is exclusive to the first list (isn't present in the second one). Now I know that for this particular silly example you could solve this using sets, but I'm just trying to illustrate a case where something like this would pop up

public List<Item> newItems(List<Item> items, List<Item> otherItems) {
    List<Item> newItems = new ArrayList<>();

    for (Item i: items) {
        for (Item j: otherItems) {
            if (i.equals(j))
                //Missing code
        }
        newItems.add(i);
    }

    return newItems;
}

So here I only want to add the current Item i to newItems if it is not equal to a single item in otherItems. My first impulse was to put break; where it says //Missing Code, but that would only break out of the first loop and not impede the adding of i to newItems.

I am aware of a correct solution where you would use a boolean variable to consistently check the truth of the if statement, and then add Item i to newItems based on it's truth value at the end of the second loop. It would look something like this:

for (Item i: items) {
    boolean check = true;

    for (Item j: otherItems) {
        if (i.equals(j))
            check = false;
            break; //To avoid unnecessary iterations
    }

    if (check)
        newItems.add(i);
}

This seems incredibly bulky and also quite redundant however. Is there a more efficient and elegant way of doing this?

like image 429
Andres Stadelmann Avatar asked Nov 17 '25 11:11

Andres Stadelmann


1 Answers

If I understand your question correctly, you need to create a list, where are collected items from items excluding items that are present in both items and otherItems. If yes, you can do it simply by List#removeAll():

public List<Item> newItems(List<Item> items, List<Item> otherItems) {
    List<Item> res = new ArrayList<>(items);  // create a copy of items
    res.removeAll(otherItems);                // remove items presented in otherItems
    return res;
}

If there are other condition(s) to exclude items, use a stream, filter(s) and collector, as follows:

return items.stream()
            .filter(i -> !otherItems.contains(i))
            .filter( /* another condition */ )
            .collect(Collectors.toList());
like image 139
Alex Salauyou Avatar answered Nov 20 '25 00:11

Alex Salauyou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!