Странно поведение на типа Array с оператор `==`

scala> List(1,2,3) == List(1,2,3)

res2: Boolean = true

scala> Map(1 -> "Olle") == Map(1 -> "Olle")

res3: Boolean = true

Но когато се опитвате да направите същото с Array, не работи по същия начин. Защо?

scala> Array('a','b') == Array('a','b')

res4: Boolean = false

Използвал съм 2.8.0.RC7 и 2.8.0.Beta1-prerelease.


person olle kullberg    schedule 09.07.2010    source източник
comment
Забележка: Можете да търсите всички свързани с scala въпроси за масив с [scala] [масив]   -  person oluies    schedule 09.07.2010
comment
възможен дубликат на Защо ` Array(0,1,2) == Array(0,1,2)` не връща очаквания резултат?   -  person Suma    schedule 21.01.2015


Отговори (2)


Тъй като дефиницията на „равно“ за масиви е, че те се отнасят за един и същ масив.

Това е в съответствие с равенството на масивите на Java, използвайки Object.Equals, така че сравнява препратките.

Ако искате да проверите елементи по двойки, използвайте sameElements

Array('a','b').sameElements(Array('a','b'))

или deepEquals, което е отхвърлено в 2.8, така че вместо това използвайте:

Array('a','b').deep.equals(Array('a','b').deep)

Има добра дискусия в Nabble относно равенството на масив.

person Stephen    schedule 09.07.2010
comment
Array ли е единственото изключение от общото правило за сравняване на действителните елементи за вградените колекции? Всички други колекции, които съм пробвал, сравняват елементите. - person olle kullberg; 09.07.2010
comment
@olle - доколкото знам, това е единствената колекция, която проявява това поведение. Дори ArrayList сравнява елементи. Това, което не мога да разбера, е как това трябва да се научи от документацията :) - person Stephen; 09.07.2010
comment
вижте също stackoverflow.com/questions/2481149/ - person oluies; 09.07.2010
comment
@olle : Java масивът е обект ( java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html , особено раздел 10.8) WrappedArray обвива java масива в клас. Array е java масивът. Причината, поради която не може да замени Object.equals (и да предостави специализирано равно), е, че не подкласира java масива. Ако обвие масива или го подкласира, ще се държи както очаквате. Трябва да кажа, че отговорът ми е напълно точен, с изключение на това, че не навлизам в подробности за защо не може да отмени поведението. - person Stephen; 10.07.2010
comment
@olle : Между другото, вашето обяснение е фактически неправилно, когато казвате правилното обяснение ... Ако не го приемете, добре, но -1 добавя обида към нараняване! :) - person Stephen; 10.07.2010
comment
Лошото ми, прав си! Четох в Beyond Java (B. Tate), че Java масивът не е обект, но както казахте, това не е вярно. - person olle kullberg; 12.07.2010
comment
@olle : Благодаря, че изясни това. И ще стоя далеч от тази книга :) - person Stephen; 12.07.2010

Основната причина е този факт, че Scala използва същата имплементация на Array като Java и това е единствената колекция, която не поддържа == като оператор за равенство.

Също така е важно да се отбележи, че избраният отговор предлага еднакво sameElements и deep сравнение, когато всъщност се предпочита да се използва:

Array('a','b').deep.equals(Array('a','b').deep)

Или, защото сега можем да използваме == отново:

Array('a','b').deep == Array('a','b').deep

Вместо:

Array('a','b').sameElements(Array('a','b'))

Тъй като sameElements не работи за вложен масив, той не е рекурсивен. И deep сравнение ще.

person Johnny    schedule 12.04.2018
comment
Любопитно е, че от Scala 2.13.0, .deep вече не е член на Array. - person jwvh; 01.07.2020