Groovy语言:如何在两个对列表之间获得差异

Iva*_*lin 6 syntax groovy list map

我试图在Groovy语言中获得另一个对的列表.对只是(x,y)坐标,它们是唯一的.以下是一个简单的小例子.请注意,列表可以有几十对.

  def l1 = [[x:1, y:1]]
  def l2 = [[x:0, y:0]]
  println l1 - l2
Run Code Online (Sandbox Code Playgroud)

会得到[],这是一个空列表,但应该是这样的:[[x:1​​,y:1]]

更新:

 for(n in l2) {
   l1 = l1 - n
 }
Run Code Online (Sandbox Code Playgroud)

它有效,但它是一个黑魔法,并没有优化

cfr*_*ick 6

如评论中所述,对中的对l1是唯一的(或者更确切地说:它可以有独特的结果),然后你可以使用l1/l2作为集合:

l1 = [[x:1, y:1]]
l2 = [[x:0, y:0]]
println l1.toSet()-l2.toSet()
//; [[x:1, y:1]]
Run Code Online (Sandbox Code Playgroud)

最初的问题是[x:0,y:0]vs [x:1,y:1]部分.原因在于public static <T> Collection<T> minus(Collection<T> self, Collection<?> removeMe).选择n*n个分支,并且NumberAwareComperator认为两个映射都相等:

def cmp = new org.codehaus.groovy.runtime.NumberAwareComparator()
println cmp.compare(l1[0], l2[0])
//; 0 (equal!)
Run Code Online (Sandbox Code Playgroud)

这简单归结为:

assert [x:1, y:1].hashCode() == [x:0, y:0].hashCode()
    // 120^1 + 121^1 == 120^0 + 121^0
Run Code Online (Sandbox Code Playgroud)

编辑替代方案(如果你可以摆脱地图)

由于这看起来不是很好的基础,你可能最好使用保存和声音类似的数据类.例如:

@groovy.transform.Immutable
class Pair {
    long x,y
}

def p00 = new Pair(0,0)
def p11 = new Pair(1,1)
def p11o = new Pair(1,1)

assert [p00]-[p11] == [p00]
assert [p11]-[p00] == [p11]
assert [p00].intersect([p11]) == []
assert [p11].intersect([p00]) == []
assert [p11].intersect([p11o]) == [p11]
assert [p11].intersect([p11o]) == [p11o]
Run Code Online (Sandbox Code Playgroud)

即使将地图转换为Expandos也可以更好地工作.