Groovy: Difference with a.intersect( b ) and b.intersect( a )
If you look at the source for Collection.intersect
, you can see that the logic of the method follows this flow:
for two collections, left
and right
- Swap
left
andright
ifleft
is smaller thanright
- Add all of
left
into a Set (removes duplicates) - For each element in
right
if it exists in theleftSet
, then add it to the results
So, for your last 2 examples;
def array1 = ["hello", "world", "test", "test"]def array2 = ["world", "world", "world", "test"]
array1.intersect( array2 )
would give (if we wrote that same algorithm in Groovy):
leftSet = new TreeSet( array1 ) // both same size, so no swap// leftSet = [ 'hello', 'world', 'test' ]right = array2result = right.findAll { e -> leftSet.contains( e ) }
Which (if you run it), you can see means result has the value [world, world, world, test]
(as you found). This is because every element in right
can be found in the leftSet
Not sure why the first example should return ["world","world"]
though...
later...
So, what I think you are looking for would be something like this:
def array1 = ["hello", "world", "test", "test"]def array2 = ["world", "world", "world", "test"]def intersect1 = array1.intersect( array2 ) as TreeSetdef intersect2 = array2.intersect( array1 ) as TreeSetassert intersect1 == intersect2
in order that you cope with the duplicates in the collections, as then both intersect1
and intersect2
will be equal to
[test, world]
later still
I believe this does what you want:
[array1,array2]*.groupBy{it}.with { a, b -> assert a == b }