I highly recommend using Adrian's solution using
removeAll(), but that aside, I think the issue with your posted code is that you're breaking out of the inner loop on the first non-match.
I don't think there's any situation where that logic alone would produce the result you expect (except for when both lists are exactly the same size, and have exactly the same order).
Consider the following collections:
The difference between the two collections, which is what you're looking for, is
The very first comparison that you make in your inner loop would be
a != d. That alone doesn't give you enough information to determine if
d exists elsewhere in the first collection, or if
a exists elsewhere in the second collection.
The issue gets worse when you consider the next match that your logic would test,
b != d. By looking at the two collections ourselves, we can see that
b exists in both collections, but your code hasn't yet encountered that value in the second collection.
Ordering the two collections would help a little, but that alone wouldn't fix your issues. To completely solve your problem, you would also need to know at which point it becomes impossible to find the target value in the second set.
You'd also need to track the largest value in the first collection (i.e. the last iteration of the outer loop), and add all elements from the second collection that are greater than that. Without that, you'd miss some elements if your second collection has more objects than your first collection.
Without using the
Set collection methods, you can't really do much better than O(n^2). The resulting code might look like this:
set<id> setAssetIds = new set<id>();
List<String> unmatchedNames = new List<String>();
list<Asset_Store__c> assets = [select id,name...... ORDER BY Name ASC];
for(Asset_Store__c item : assets )
list<Meter__c> meters = [select id,name......where id in : setAssetIds ORDER BY Name ASC];
// Store the largest sorted value of the Asset_Store__c records so we know when we're in
// the last iteration of the outer loop
String assetLastName = assets[assets.size()-1];
//now comparing the two lists
for(Asset_Store__c a : assets)
matched = false;
for(Meter__c m : meters)
if(a.Name == m.Name)
// Once we know that we have a match, we can move on to the next
// iteration of the outer loop
matched = true;
else if(a.Name < m.name)
if(a.Name == assetLastName)
// We're in the last iteration of the outer loop, and there's
// no possibility that any other name in the meters list can match.
// These names must be added to the difference list.
// It is impossible to match the asset name further in the meter list at this point.
// This should also take care of the case where a.name is sorted
// lower than any name in meters.
// Break to save some cycles
// We cannot add names from the asset list to our unmatched list before
// this point.
// Doing so would mean we left some possible names untested
Now that I'm done rambling, DON'T USE THIS CODE.
Set.removeAll(), or at the very least