다음 예를 통해 같음의 사용법을 익히세요
package cn.galc.test;public class TestEquals { public static void main(String[] args) { /** * 여기에서는 Cat() 생성 메서드를 사용하여 힙 메모리에 두 개의 새로운 고양이를 생성합니다. 색상, 무게, 키는 모두 동일하지만 * c1과 c2는 결코 동일하지 않습니다. 이는 c1과 c2가 힙 메모리에 있는 두 고양이의 참조 객체이기 때문입니다. 두 마리의 고양이를 찾을 수 있는 주소가 포함되어 있지만 두 마리의 고양이는 힙 메모리의 서로 다른 두 공간에 저장되므로 *c1과 c2는 서로 다른 주소를 포함하므로 c1과 c2는 결코 동일하지 않습니다. */ Cat c1 = new Cat(1, 1, 1); Cat c2 = new Cat(1, 1, 1); System.out.println("c1==c2의 결과는 다음과 같습니다: "+(c1== c2 ));//false System.out.println("c1.equals(c2)의 결과는 다음과 같습니다: "+c1.equals(c2));//false }}class Cat { int color, 체중, 신장; public Cat(int color, int Weight, int height) { this.color = color; this.height = height }}c1과 c2의 비교 결과를 분석하기 위해 메모리 분석 다이어그램을 작성합니다.
프로그램:
Cat c1 = 새 Cat(1,1,1);Cat c2 = 새 Cat(1,1,1);
실행 후 메모리의 레이아웃은 다음과 같습니다.
c1은 객체를 가리키고 c2도 객체를 가리킵니다. C1과 c2는 이 두 Cat 객체의 힙 메모리에 저장된 주소를 포함합니다. 두 Cat 객체는 서로 다른 저장 공간에 위치하므로 c1과 c2는 다음의 주소를 포함합니다. 은 확실히 동일하지 않으므로 두 참조 개체 c1과 c2는 확실히 동일하지 않습니다. 따라서 "System.out.println(c1==c2);"을 실행하면 인쇄된 결과는 확실히 false입니다. 따라서 new를 사용하여 두 개의 개체를 생성하면 두 개체의 참조가 동일하지 않으므로 그 중 하나를 덮어쓸 수 없습니다. c1이 c2와 같은지 여부는 두 참조 c1 및 c2에 포함된 내용을 비교합니다. 왜냐하면 new에 의해 생성된 두 개체의 참조는 결코 동일하지 않으므로 두 참조 c1 및 c2의 내용도 결코 동일하지 않기 때문입니다. c1은 결코 c2와 같을 수 없습니다. 따라서 두 개체의 참조를 비교하면 두 개체가 동일하거나 동일해질 수 없습니다.
두 객체가 동일한지 확인하려면 두 객체의 참조가 동일한지 비교할 수 없습니다. 두 객체의 참조는 결코 동일하지 않으므로 동일한 결과를 얻을 수 없으므로 이를 직접 비교하는 것이 올바른 비교 방법입니다. 두 객체를 비교하고 두 객체의 본질이 동일한지, 즉 두 객체의 내용이 동일한지 비교하여 두 객체의 속성값이 동일한지 여부를 판단합니다. 동일합니다.
Object 클래스는 두 객체의 내용이 동일한지 비교하는 equals() 메소드를 제공하므로 이 메소드를 사용하여 두 객체가 논리적으로 "동일"한지 비교할 수 있습니다. 예: c1.equals(c2); 다음은 Object 클래스에서 상속된 equals() 메소드에 대한 호출입니다. API 문서를 참조하면 Object 클래스의 equals 메소드 정의는 다음과 같습니다.
공개 부울은 같음(객체 obj)
Object 클래스에 제공되는 Equals() 메서드의 기본 구현은 현재 개체의 참조와 비교하려는 참조를 비교하여 동일한 개체를 가리키는지 확인하는 것입니다. 이는 "c1==c2와 동일합니다. ". , "c1.equals(c2)" 및 "c1==c2"는 완전히 동일합니다. 따라서 상속된 equals() 메서드를 직접 사용하면 두 객체의 내용이 동일한지 직접 비교할 수 없습니다. 이러한 이유로 우리는 equals() 메서드를 재정의하고 이 메서드의 기본 구현을 변경해야 합니다.
다음으로 Cat 클래스에서 상속된 equals() 메서드를 다시 작성합니다.
class Cat { int color, Weight, height; public Cat(int color, int Weight, int height) { this.color = color; this.weight = this.height = height } /** * 이는 평등을 다시 작성하는 것입니다. Object 클래스에서 상속된 equals() 메소드는 이 메소드의 기본 구현을 변경합니다. * 두 객체가 논리적으로 동일한지 확인하려면 자체 정의된 구현을 사용합니다. * 여기서 우리는 두 고양이의 색깔, 몸무게, 키가 동일하다면 * 두 고양이가 논리적으로 동일하다고, 즉 두 고양이가 "동등하다"고 생각한다고 정의합니다. */ public boolean equals(Object obj){ if (obj==null){ return false; } else{ /** * instanceof는 객체 연산자입니다. * 객체 연산자는 객체가 지정된 클래스 또는 지정된 하위 클래스의 인스턴스에 속하는지 여부를 확인하는 데 사용됩니다. * 객체연산자는 인스턴스오브(instanceof)라는 단어를 결합한 것입니다. * 이 연산자는 이항 연산자입니다. 왼쪽의 식이 객체이고 오른쪽의 식이 클래스입니다. * 왼쪽의 객체가 오른쪽의 클래스에서 생성된 객체인 경우 연산 결과는 다음과 같습니다. true, 그렇지 않으면 false입니다. */ if (obj 인스턴스of Cat){ Cat c = (Cat)obj; if (c.color==this.color && c.weight==this.weight && c.height==this.height){ return true; } } } 거짓을 반환 }} 이때 기본 메소드에서 인쇄 명령을 실행합니다.
public static void main(String[] args) { /** * 여기서는 Cat() 생성 메소드를 사용하여 힙 메모리에 두 마리의 새 고양이를 생성합니다. * 이 두 고양이의 색상, 무게, 키는 동일합니다. * 그러나 c1과 c2는 결코 동일하지 않습니다. 이는 c1과 c2가 힙 메모리에 있는 두 고양이의 참조 개체이기 때문입니다. * 두 고양이를 찾을 수 있는 주소가 포함되어 있지만 힙 메모리 두 개의 서로 다른 공간에 * 따라서 c1과 c2는 서로 다른 주소를 보유하므로 c1과 c2는 결코 동일하지 않습니다. */ Cat c1 = new Cat(1, 1, 1); Cat c2 = new Cat(1, 1, 1); System.out.println("c1==c2의 결과는 다음과 같습니다: "+(c1== c2 ));//false System.out.println("c1.equals(c2)의 결과는 다음과 같습니다: "+c1.equals(c2));//true }이번에 얻은 결과는 이전에 equals() 메서드를 재정의하지 않고 얻은 결과와 다릅니다.
"System.out.println(c1 == c2);" 두 개체의 참조 내용이 비교되기 때문에 인쇄된 결과는 여전히 false입니다. 동일하므로 인쇄된 결과는 거짓이어야 합니다.
"System.out.println(c1.equals(c2));" Cat 클래스의 equals() 메서드를 다시 작성하고 이 메서드의 기본 구현을 변경했기 때문에 인쇄된 결과는 true입니다. 방법은 다음으로만 변경됩니다. 이 두 물체가 실제로 존재하고 둘 다 고양이이고 색깔, 키, 몸무게가 동일하다면 두 고양이는 논리적으로 동일하고 완전히 동일합니다. 즉, 이 두 고양이는 "동일"합니다. 따라서 여기에 인쇄된 결과는 사실입니다.
그렇다면 두 문자열 객체가 같은지 비교하는 방법은 무엇입니까?
다음 예를 살펴보십시오.
public class TestEquals { public static void main(String args[]){ String s1 = new String("hello"); String s2 = new String("hello"); System.out.println("s1 == s2 결과 : "+(s1 == s2));//false System.out.println("s1.equals(s2)의 결과는 다음과 같습니다: "+s1.equals(s2));//true }}이번에는 두 문자열 객체가 동일한지 비교됩니다.
System.out.println(s1 == s2);
두 문자열 객체 s1과 s2의 참조가 여기에서 비교되기 때문에 인쇄된 결과는 여전히 false입니다. 따라서 인쇄된 결과는 false입니다.
System.out.println(s1.equals(s2));
Object 클래스의 상속이 String 클래스에서 다시 작성되었기 때문에 인쇄된 결과는 true입니다(모든 클래스는 Object 클래스에서 상속되며 물론 String 클래스도 예외는 아닙니다. 상위 클래스에서 상속하면 모든 것을 갖습니다. 따라서 Sting 클래스에도 equals() 메서드가 있고 상속된 equals() 메서드도 다시 작성되어 이 메서드의 기본 구현이 변경되었습니다.
String 클래스에서 equals() 메소드의 구현은 다음과 같이 재정의됩니다. 즉, 현재 문자열 객체를 지정된 문자열 객체와 비교합니다. 지정된 문자열 객체는 비어 있을 수 없으며 이 객체의 문자 시퀀스는 현재 문자열과 동일합니다. . 객체의 문자열 시퀀스는 동일합니다. 이러한 조건이 충족되면 두 문자열 객체는 동일합니다.
따라서 여기의 s2는 조건을 만족하므로 인쇄된 결과는 true입니다.
앞으로 특정 클래스의 두 객체가 동일한지 비교할 때 먼저 API 문서로 이동하여 이 클래스가 Object 클래스에서 상속된 equals() 메서드를 재정의했는지 확인하세요. equals() 메서드가 재정의되면 두 객체가 동일한지 비교할 때 재정의된 equals() 메서드가 호출되고, 재정의되지 않으면 Object 클래스에서 상속된 메서드가 직접 호출됩니다. 두 객체가 같은지 비교하기 위해 equals() 메소드의 기본 구현을 사용합니다. 따라서 각 클래스는 필요에 따라 Object 클래스에서 상속된 equals() 메서드를 재정의할 수 있습니다.
API 문서에서 특정 클래스를 찾으려면 패키지를 도입하지 않고 직접 사용할 수 있는 클래스라면 이 클래스가 java.lang 패키지에 있어야 합니다. 예를 들어 여기서는 String 클래스를 직접 사용할 수 있으므로 String 클래스를 사용합니다. 필수입니다. java.lang 패키지에 있습니다. 특정 클래스를 사용할 경우 해당 클래스가 어떤 패키지를 임포트하는지 확인한 후 해당 패키지로 이동하여 해당 클래스를 찾으세요. 패키지를 임포트할 필요가 없는 클래스는 java.lang에 직접 가서 찾으시면 됩니다. .
일반적으로 클래스를 디자인할 때 상위 클래스의 equals 메소드를 재정의해야 합니다. 이 메소드를 다시 작성할 때는 다음 규칙에 따라 디자인해야 합니다.
1. 재귀성: 참조 값 X에 대해 x.equals(x)의 반환 값은 true여야 합니다.
2. 대칭: 모든 참조 값 x, y에 대해 y.equals(x)의 반환 값이 true인 경우에만 x.equals(y)의 반환 값은 true여야 합니다.
3. 전이성: x.equals(y)=true, y.equals(z)=true이면 x.equals(z)=true
4. 일관성: 비교에 참여하는 개체가 변경되지 않으면 개체 비교 결과도 변경되어서는 안 됩니다.
5. Null 허용 여부: Null이 아닌 참조 값 X의 경우 x.equals(null)의 반환 값은 false여야 합니다.
예를 들어:
공개 클래스 사람들 { 비공개 문자열 lastName; 공개 문자열 getFirstName() { 반환 firstName } 공개 void setFirstName(String firstName) } 공개 문자열 getLastName(); } 공개 void setLastName(String lastName) { this.lastName = lastName } 공개 int getAge() { 반환 연령 } 공개 void setAge(int age); this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; return false; People other = (People) obj; if (age != other.age) return false if (firstName == null) { if (other.firstName != null) return false; (!firstName.equals(other.firstName)) return false; if (lastName == null) { if (other.lastName != null) return false } else if (!lastName.equals(other.lastName)) return false; ; 참을 반환합니다 }}
이 예에서는 성, 이름, 나이가 동일하면 그 사람은 동일인이라고 규정합니다. 물론, 다른 속성도 추가할 수 있습니다. 예를 들어 ID번호가 동일해야 동일인으로 판단됩니다. 그러면 Equals 메소드에 ID번호 판단을 추가할 수 있습니다.
요약: 두 객체가 동일한지 비교하기 위해 equals() 메서드를 사용합니다. 두 객체가 동일한지 여부를 판단하는 조건은 equals() 메서드의 구현을 다시 작성한 후 정의합니다. 더 유연하게 사용할 수 있습니다. 서로 다른 클래스에 있는 동일한 클래스의 두 개체를 비교하여 동일한지 확인하세요.