Функция .contains () не работает в Groovy ожидаемым образом - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь проверить, является ли число членом списка, используя язык программирования Groovy.

У меня есть этот кусок кода:

List<Long> list = [1, 2, 3]
Long number = 3

println(list.contains(number))​

Ожидаемый результат - true, но результат, который я получаю - false.

У кого-нибудь есть объяснение?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Параметры общего типа не отображаются во время выполнения. Проверьте это:

List<Long> list = [1, 2, 3]
list.each{println it.getClass()}

Какие отпечатки:

class java.lang.Integer
class java.lang.Integer
class java.lang.Integer

Истинная путаница возникает из-за странного различия в поведении между реализациями .equals и ==:

Long.valueOf(3).equals(Integer.valueOf(3))
===> false
Long.valueOf(3) == Integer.valueOf(3)
===> true

List.contains, похоже, использует .equals, который проверяет класс параметра, объясняя, таким образом, что принудительное обращение с типами элементов к Long решает проблему.

Итак, в разгар этой неопределенности, я думаю, единственно верным является то, что выполнение == Groovy выполняет наиболее интуитивное и предсказуемое сравнение. Поэтому я бы изменил чек на:

boolean contains = list.grep{it == 3L} //sets value to true if matches at least 1

Это помогает, когда не нужно знать типы данных, связанные с литералами:

def ints = [1, 2, 3]
def longs = [1L, 2L, 3L]

boolean found1 = ints.grep{it == 3L}
boolean found2 = ints.grep{it == 3}
boolean found3 = longs.grep{it == 3L}
boolean found4 = longs.grep{it == 3}

println found1
println found2
println found3
println found4

Который работает так, как хотелось бы:

true
true
true
true
0 голосов
/ 30 апреля 2018

Вы должны использовать специальные литеральные значения для длинных: 1L вместо 1.

List<Long> list = [1L, 2L, 3L]
Long number = 3L

1 является инт. 1L длинный.

...