==, equals(), contains()

박영준·2023년 3월 16일
0

Java

목록 보기
50/112

1. ==

1) 정의

주소값을 비교

  • 기본형에 대해서는 "값"을 비교
    참조형에 대해서는 "객체 주솟값"을 비교

  • Call by Value (값에 의한 호출) 형태

  • == 으로 비교한 두 개의 값은 서로 다르다.
    → 참조 타입의 변수의 값은 힙 영역의 객체 주소이므로, 결국 주소 값을 비교하는 것이 되어 다르다는 결론이 나온다.
    → 따라서, Java 에서 문자열 비교 비교 시, equals() 메서드를 활용하여 두 개의 값을 비교해주어야 한다.

    기본형 vs 참조형
    기본형 (Primitive Type) : 실제 데이터를 저장

    참조형 (Reference Type) : 실제 데이터가 아닌 데이터가 저장되어 있는 '주소'를 저장

2) 사용 상황

  • 동일한 객체를 참조하는지 알아볼 때

  • 다른 객체를 참조하는지 알아볼 때

  • 일반적인 데이터 타입(int, char, boolean 등...의 primitive type(원시 타입))의 비교에 사용

3) 예시

  1. //str1과 str2 선언
    String str1 = "hello";
    
    Scanner sc = new Scanner(System.in);
    String str2 = sc.next();
    
    //str1과 str2를 비교하고 조건문 실행
    if(str1==str2) {
        System.out.println("입력 내용 일치!");
    }else {
        System.out.println("입력 내용이 일치하지 않습니다.");
    }
    
    //str1==str2가 true/false가 나오는지 확인
    System.out.println(str1==str2);
    // 출력 결과
    hello
    입력 내용이 일치하지 않습니다.
    false

    false 가 나오는 이유?
    str1과 str2의 값이 "hello"로 같지만
    사실은 문자열인 "hello"가 저장되는 것이 아니라, "hello" 가 존재하는 객체의 주소가 저장되는 것
    → String 은 참조형이다!

    참고: 입출력 스트림, 보조 스트림, 입출력 API - 1. System.in 필드

  2. public class compare {
        public static void main(String[] args) {
            String s1 = "abcd";
            String s2 = new String("abcd");
    
            if(s1 == s2) {
                System.out.println("두개의 값이 같습니다.");
            }else {
                System.out.println("두개의 값이 같지 않습니다.");
            }
        }
    }

2. equals()

1) 정의

값 자체를 비교

  • 문자열 비교에 사용

  • 일차원 배열에만 사용

  • call-by-reference (참조에 의한 호출) 형태

  • 최상위 클래스인 Object에 포함되어 있기 때문에, 모든 하위 클래스에서 재정의해서 사용 가능

    • (Object에 있는 메서드와 달리) Objects의 equals()는 null 검사를 하지 않아도 됨
      → 메소드의 내부에서 a와 b의 null 검사를 하기 때문
  • 동일한 객체가 메모리 상에 여러 개 띄워져있는 경우가 있다.
    해당 객체는 서로 다른 메모리에 띄워져있으므로 동일한 객체가 아니다.
    하지만 프로그래밍 상으로는 같은 값을 지니므로 같은 객체로 인식되어야 하는데,
    이러한 동등성을 위해 값으로 객체를 비교하도록 equals 메소드를 오버라이딩한다.

  • boolean 타입이다.
    → 즉, true/false 의 결과가 나옴

2) 사용 상황

  • Class 값의 비교에 사용

  • String 간에 값을 비교할 때

  • 2개의 객체가 동일한지 검사하기 위해 (동일성(Identity)을 비교)
    → 2개의 객체가 가리키는 곳이 동일한 메모리 주소일 경우에만 동일한 객체가 된다.

3) 예시

  1. public class compare {
        public static void main(String[] args) {
            String s1 = "abcd";
            String s2 = new String("abcd");
    
            if(s1.equals(s2)) {
                System.out.println("두개의 값이 같습니다.");
            }else {
                System.out.println("두개의 값이 같지 않습니다.");
            }
        }
    }

    • String 클래스 안에 있는 equals() 메서드로 비교한 두 개의 값은 같다.
      • String 은 일반적인 타입이 아니라 클래스다.
        클래스는 생성 시 주소값이 부여되므로, String 타입을 선언했을 때는 같은 값을 부여하더라도 서로간의 주소값이 다르다.
      • 두 비교 대상의 주소 값이 아닌 데이터 값(값 자체)을 비교하기 때문
        → 어떻게 String 을 생성하느냐에 따라 결과가 달라지지 않고 정확한 비교가 가능
  2. String s1 = new String("Test");
    String s2 = new String("Test");
    
    System.out.println(s1 == s2);			// false
    System.out.println(s1.equals(s2));		// true;
    
    // equals, overridden in String Class 
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
    
        return false;
    }
  3. class Operator6_2 {
        public static void main(String[] args) {
    
            String s1 = "사랑";
            String s2 = "사랑";
    
            // 문자열 s1 과 s2 는 같은 주소를 가지므로, == 를 통한 주소값 비교에서 true가 나온다.
            System.out.print("s1 == s2 = "); // true
            System.out.println(s1 == s2);
            System.out.println("s1.equals(s2) = " + s1.equals(s2)); // true
    
            // 문자열 s1 과 s3 는 다른 주소를 가지므로, == 를 통한 주소값 비교에서 false가 나온다. (new 연산자를 통한 생성은 다른 주소값을 갖게 만듦)
            String s3 = new String("사랑");
            System.out.print("s1 == s3 = "); // false
            System.out.println(s1 == s3);
            System.out.println("s1.equals(s3) = " + s1.equals(s3)); // true
        }
    }
  4. String s1 = "hi";
    String s3 = "hi";
    String s4 = "HI";
    
    System.out.println(s1.equalsIgnoreCase(s4));
    • 대소문자를 구분하기 때문에, 대소문자 구분 없이 확인하고 싶다면 equalsIgnoreCase() 를 사용할 수 있다.

4) deepEquals()

  • equals보다 깊게 비교하는 메소드

  • 다차원 배열에서 사용 (2차 배열, 3차 배열 ...)

  • 문자열 비교에 사용

5) equalsIgnoreCase

  • equals : 대소분자를 구분해서 판단
  • equalsIgnoreCase : 대소문자 구분하지 않고 판단

3. contains()

1) 정의

  • 특정 문자열이 포함되어 있는지 확인

  • true or false를 반환한다.

2) equals() 와 contains()

equals()

  • 문자열 동일 유무 확인

  • 문자열이 서로 100% 일치해야만 true가 리턴된다.

contains()

  • 문자열 포함 유무 확인

  • 문자열이 서로 100% 일치하지 않더라도, 포함되기만 하면 true가 리턴된다.

3) 예시

String s1 = "Hello world, java";

System.out.println(s1.toUpperCase().contains("JaVa".toUpperCase()));
System.out.println(s1.toUpperCase().contains("h".toUpperCase()));
  • 대소문자를 구분하기 때문에, 대소문자 구분 없이 확인하고 싶다면 toUpperCase()나 toLowerCase() 를 사용할 수 있다.

참고: [Java] 문자열 비교하기 == , equals() 의 차이점
참고: [TIL][Java] equals()메소드 vs ==연산자 비교하기
참고: [Java] String 변수를 == 로 비교할 때 : 똑같은 값인데, 왜 false가 나오죠?
참고: [Java] equals와 hashCode 함수
참고: [Java] String 클래스 - contains,equals의 차이
참고: 자바 문자열이 포함되어 있는지 확인하는 함수 - contains vs equal
참고: [JAVA] String 문자열 클래스 - contains / equals

profile
개발자로 거듭나기!

0개의 댓글