Groovy:与a.intersect(b)和b.intersect(a)的区别

div*_*ges 7 arrays groovy intersect

为什么在Groovy中,当我创建2个列表时,如果我执行a.intersect(b)和b.intersect(a)会有区别:

def list1 = ["hello", "world", "world"];
def list2 = ["world", "world", "world"];

println( "Intersect list1 with list2: " + list1.intersect( list2 ) );
println( "Intersect list2 with list1: " + list2.intersect( list1) );
Run Code Online (Sandbox Code Playgroud)

痕迹:

Intersect list1 with list2: [world, world, world]
Intersect list2 with list1: [world, world]
Run Code Online (Sandbox Code Playgroud)

(你可以在这里复制:http://groovyconsole.appspot.com/如果你想测试它)

如果数组都包含唯一元素,那么它可以正常工作.一旦你开始添加重复项,它就会变得奇怪:

def list1 = ["hello", "world", "test", "test"];
def list2 = ["world", "world", "world", "test"];

println( "Intersect list1 with list2: " + list1.intersect( list2 ) );
println( "Intersect list2 with list1: " + list2.intersect( list1 ) );
Run Code Online (Sandbox Code Playgroud)

痕迹:

Intersect list1 with list2: [world, world, world, test]
Intersect list2 with list1: [world, test, test]
Run Code Online (Sandbox Code Playgroud)

我认为重点intersect()是给你共同的元素,所以你把它们放在哪个顺序并不重要?

如果不是这种情况,我怎样才能获得公共元素(期望数组中的重复元素).例如,一个应该返回["world", "world"],示例二应该返回["world", "test"]

编辑

为了澄清一点,这段代码应该测试用户数据是否仍然相同(假设它们在某些东西中断开,我们想确保数据没有被篡改,或者处于与之前相同的状态).

无法保证列表的顺序(用户可以重新排序,但它在技术上仍然是"相同的"),并且可以重复.

所以类似于:["one", "one", "two"]匹配["two", "one", "one"],而列表的任何添加或数据的更改都不匹配.

tim*_*tes 9

如果查看源代码Collection.intersect,可以看到该方法的逻辑遵循以下流程:

两个集合,leftright

  1. 交换left,right如果left小于right
  2. 将所有内容添加left到集合中(删除重复项)
  3. 对于每个元素right是否存在于其中leftSet,然后将其添加到结果中

那么,对于你的最后两个例子;

def array1 = ["hello", "world", "test", "test"]
def array2 = ["world", "world", "world", "test"]
Run Code Online (Sandbox Code Playgroud)

array1.intersect( array2 ) 会给(如果我们在Groovy中编写相同的算法):

leftSet = new TreeSet( array1 ) // both same size, so no swap
// leftSet = [ 'hello', 'world', 'test' ]
right   = array2
result = right.findAll { e -> leftSet.contains( e ) }
Run Code Online (Sandbox Code Playgroud)

哪个(如果你运行它),你可以看到意味着结果具有值[world, world, world, test](如你所发现的).这是因为right可以在中找到每个元素leftSet

不知道为什么第一个例子应该返回["world","world"]...

后来...

所以,我认为你正在寻找的是这样的:

def array1 = ["hello", "world", "test", "test"]
def array2 = ["world", "world", "world", "test"]
def intersect1 = array1.intersect( array2 ) as TreeSet
def intersect2 = array2.intersect( array1 ) as TreeSet
assert intersect1 == intersect2
Run Code Online (Sandbox Code Playgroud)

为了使你应付集合重复的,因为那么这两个intersect1intersect2将等于

[test, world]
Run Code Online (Sandbox Code Playgroud)

后来还是

我相信这可以做你想要的:

[array1,array2]*.groupBy{it}.with { a, b -> assert a == b }
Run Code Online (Sandbox Code Playgroud)