name_masked
name_masked

Reputation: 9794

Find non-matching subset of elements in the array - java

Given 2 arrays of String values such as:

String[] a1 = {"A", "B", "C"}  
String[] a2 = {"A", "B"};  

where one array(a1) contains all the available String values and another array(a2) contains value I do not want to consider, how can I return an array with elements from a1 not contained in a2?

Constraints:
1> a1 and a2 will always contain unique valid values i.e. any value in a2 will always be a value from a1 and so there can never be a mismatch between a1 and a2)
2> a2 can be empty array

Here is what I have in mind:

List<String> nonMatch = new ArrayList<String>(a1.length - a2.length);
for (String a : a2)
{
    if (Arrays.binarySearch(a1, a) < 0)
    {
            nonMatch.add(a);
     }
}
return nonMatch.toArray();

But I wanted to know if there are any better solutions without degrading with performance

Upvotes: 4

Views: 2563

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500435

I would use a Set<T> - probably a HashSet<T>. For example:

Set<String> results = new HashSet<String>(Arrays.asList(a1));
results.removeAll(Arrays.asList(a2));
return results; // Convert to an array if you really must

EDIT: My previous edit seems to have got lost, annoyingly.

I personally wouldn't convert back to an array unless you've got a compelling reason to do so. Life is generally more pleasant in Java if you stick to the Java Collection APIs (List, Set, Map etc) rather than arrays. You should also look at Guava which contains a bunch of nice functionality. In this particular case it wouldn't do much to improve things:

Set<String> results = Sets.newHashSet(a1);
results.removeAll(Arrays.asList(a2));
return results;

... but in general it's an incredibly useful library to have up your sleeve.

EDIT: To preserve order, use LinkedHashSet<T>:

Set<String> results = new LinkedHashSet<String>(Arrays.asList(a1));
results.removeAll(Arrays.asList(a2));
return results; // Convert to an array if you really must

Upvotes: 11

Andrew White
Andrew White

Reputation: 53496

I think a Set is probably the best way to go...

Set<String> diff = new HashSet<String>(Arrays.asList(a1));
diff.removeAll(Arrays.asList(a2));

Upvotes: 4

Related Questions