optimize nested for loops within nested if statements I am trying to optimize this code. The only optimization I can think of is to ?¿? a return or break statement after applyOfferChanges(…) inside the second if condition which does not work either because there could be multiple matches. I cannot either use a map for favoriteMerchantsList because getFavoriteMerchantsList() return type is a list (of favorited merchants). Any ideas?

void applyFavoriteChangesToMerchantStore(){

    List&lt;Merchant&gt; favoriteMerchantsList = FavoriteMerchantStore.getInstance().getFavoriteMerchantsList();
    if(favoriteMerchantsList != null &amp;&amp; !favoriteMerchantsList.isEmpty()) {
        List&lt;Merchant&gt; storeMerchantList = MerchantStore.getInstance().getMerchantList();
        for (Merchant storeMerchant : storeMerchantList) {
            for (Merchant favoriteMerchant: favoriteMerchantsList){
                if(TextUtils.equals(storeMerchant.getId(), favoriteMerchant.getId())){
                    //merchant match found
                    //set merchant favorite status

                   storeMerchant.setFavoriteMerchant(favoriteMerchant.getFavoriteMerchant());
                    //set offer favorite status
                    applyOfferChanges(favoriteMerchant.getOffferList(),
                            storeMerchant.getOffferList());
                }
            }
        }
    }
}
You are implementing an inner join as a nested loop join. There are several other ways to implement joins, such as hash-based or sort-merge sort. Which one is better depends on the length of the lists.

I will sketch a hash join as that usually works most of the time.

void applyFavoriteChangesToMerchantStore(){

    List&lt;Merchant&gt; favoriteMerchantsList = FavoriteMerchantStore.getInstance().getFavoriteMerchantsList();
    if(favoriteMerchantsList != null &amp;&amp; !favoriteMerchantsList.isEmpty()) {
        // build the hash table
        Map&lt;String, Merchant&gt; favoriteMerchantById = favoriteMerchantsList.stream().collect(Collectors.toMap(Merchant::getId, Function.identity()));
        List&lt;Merchant&gt; storeMerchantList = MerchantStore.getInstance().getMerchantList();
        for (Merchant storeMerchant : storeMerchantList) {
            // probe the hash table
            Merchant favoriteMerchant = favoriteMerchantById.get(storeMerchant.getId())
            if(favoriteMerchant != null){
                //merchant match found
                //set merchant favorite status

               storeMerchant.setFavoriteMerchant(favoriteMerchant.getFavoriteMerchant());
                //set offer favorite status
                applyOfferChanges(favoriteMerchant.getOffferList(),
                        storeMerchant.getOffferList());
            }
        }
    }
}


I assumed that TextUtils.equals is equal to String.equals. If it's more lenient (e.g., case-insensitive), you need to normalize the lookup key (e.g., String.toLowerCase()).