programing tip

스칼라에서 ==와 .equals의 차이점은 무엇입니까?

itbloger 2020. 6. 24. 07:45
반응형

스칼라에서 ==와 .equals의 차이점은 무엇입니까?


스칼라 ==의 차이점은 무엇 .equals()이며 언제 사용해야합니까?

구현이 Java와 동일합니까?

편집 : 관련 질문은의 특정 사례에 대해 이야기 AnyVal합니다. 더 일반적인 경우는 Any입니다.


일반적 으로을 (를) 올바르게 사용 하는 것을 제외하고로 ==라우팅합니다 . 참조 평등 (드물게 사용됨)은 입니다.equalsnulleq


==최종 방법이며을 호출합니다 .equals.

이것은 ==메소드가 아니라 연산자이며 객체에 대한 참조 평등을 엄격하게 비교하는 Java와 근본적으로 다릅니다 .


TL; DR

  • equals각 인스턴스의 컨텐츠를 비교하는 메소드를 대체하십시오 . 이것은 equalsJava에서 사용 된 것과 동일한 방법입니다
  • 참조 ==를 걱정하지 않고 연산자를 사용 하여 비교null
  • 사용하여 eq두 인수가 있는지 확인하는 방법을 정확하게 동일한 참조. 이것이 어떻게 작동하는지 이해하지 못하고 종종 equals필요한 것 대신 작동하는 경우가 아니라면 사용하지 않는 것이 좋습니다. 그리고 이것을 AnyRef인수가 아닌 인수 와 함께 사용해야합니다.Any

참고 : 경우에 equals당신은 예를 들어이 인수 전환하면 바로 자바로,이 같은 결과를 반환하지 않을 수 있습니다 1.equals(BigInt(1))반환 false역 반환 곳을 true. 각 구현이 특정 유형 만 검사하기 때문입니다. 기본 숫자는 두 번째 인수가 유형이 아닌 다른 기본 유형 인지 확인하지 Number않습니다.BigInt

세부

AnyRef.equals(Any)메소드는 서브 클래스로 대체 된 메소드입니다. 스칼라로 넘어온 Java 스펙의 메소드. 박스가없는 인스턴스에서 사용되는 경우이를 호출하는 박스가 있습니다 (스칼라에는 숨겨져 있지만 Java에서는 int->가 더 분명합니다 Integer). 기본 구현은 참조를 비교할뿐입니다 (Java와 동일).

Any.==(Any)메소드는 두 객체를 비교하고 두 인스턴스를 사용하여 정적 메소드를 호출하는 것처럼 두 인수를 모두 널로 허용합니다. 둘 다 인 경우를 비교 null한 다음 equals(Any)박스형 인스턴스 에서 메소드를 호출합니다 .

AnyRef.eq(AnyRef)방법은 참조, 즉 인스턴스가 메모리에있는 위치 비교 합니다 . 이 방법에는 암시 적 권투가 없습니다.

  • 1 equals 2false로 리디렉션 될 때를 반환 합니다.Integer.equals(...)
  • 1 == 2false로 리디렉션 될 때를 반환 합니다.Integer.equals(...)
  • 1 eq 2 두 인수 모두 유형이어야하므로 컴파일되지 않습니다. AnyRef
  • new ArrayList() equals new ArrayList()true내용을 확인하면서를 반환 합니다.
  • new ArrayList() == new ArrayList()true로 리디렉션 될 때를 반환 합니다.equals(...)
  • new ArrayList() eq new ArrayList()false두 인수가 서로 다른 인스턴스이므로를 반환 합니다.
  • foo equals foo반환 true하지 않는 foo것입니다 null, 다음을 던질 것이다NullPointerException
  • foo == foo반환합니다 true경우에도 foo입니다null
  • foo eq footrue두 인수가 동일한 참조에 연결되므로 가 반환됩니다.

사이에 흥미로운 차이가 ==equals에 대한 FloatDouble유형 : 그들은 치료 NaN다르게 :

scala> Double.NaN == Double.NaN
res3: Boolean = false

scala> Double.NaN equals Double.NaN
res4: Boolean = true

편집 : 의견에서 지적했듯이 "이것은 Java에서도 발생합니다" 정확히 이것이 무엇인지에 달려 있습니다 .

public static void main(final String... args) {
    final double unboxedNaN = Double.NaN;
    final Double boxedNaN = Double.valueOf(Double.NaN);

    System.out.println(unboxedNaN == unboxedNaN);
    System.out.println(boxedNaN == boxedNaN);
    System.out.println(boxedNaN.equals(boxedNaN));
}

이것은 인쇄됩니다

false
true
true

따라서 IEEE 부동 소수점 숫자가 그것을 정의하는 방식이기 때문에 평등과 비교할 때 unboxedNan수율 false은 모든 프로그래밍 언어에서 실제로 발생해야합니다 (어쨌든 정체성의 개념을 망칠지라도).

박스형 NaN은 ==객체 참조를 비교할 때 Java를 사용한 비교에 적용됩니다.

이 경우에 대한 설명이 없습니다 equals.IMHO는 실제로 상자 ==없는 이중 값 과 동일하게 작동해야 하지만 그렇지 않습니다.

Translated to Scala the matter is a little more complicated as Scala has unified primitive and object types into Any and translates into the primitive double and the boxed Double as needed. Thus the scala == apparently boils down to a comparison of primitive NaN values but equals uses the one defined on boxed Double values (there is a lot of implicit conversion magic going on and there is stuff pimped onto doubles by RichDouble).

If you really need to find out if something is actually NaN use isNaN:


In Scala == first check for Null values and then calls equals method on first object

참고URL : https://stackoverflow.com/questions/7681161/whats-the-difference-between-and-equals-in-scala

반응형