회고록 블로그

[자료구조] 네이버 부스트코스 '자바로 구현하고 배우는 자료구조' 공부 필기 (4) 본문

3. Computer Science 공부/자료구조

[자료구조] 네이버 부스트코스 '자바로 구현하고 배우는 자료구조' 공부 필기 (4)

김간장 2021. 11. 23. 23:58

시간날때마다 자료구조 강의를 청강하려고 노력중..

 

 

출처 강의 : '자바로 구현하고 배우는 자료구조', Rob Edwards, https://www.boostcourse.org/cs204/joinLectures/145114

 

자바로 구현하고 배우는 자료구조

부스트코스 무료 강의

www.boostcourse.org

 

※ 강의 들으며, 개인적으로 필요한 내용만 필기함

 

 

※ 본 글은 강의 내용을 여러번 청강하고 혼자 깨달음을 얻으며 필기한 글임

※ 강의 자체는 너무 명강의이고 교수님도 명강사이지만,

      필자의 이해력이 부족해서(ㅜㅜ) 맞지 않는 사실이 존재할 수 있음 + 교수님의 설명(혹은 의도)과 다른 내용이 있을 수 있음..

 


1. Comparable 인터페이스

 

[개요]

- 객체에서 숫자, 문자열 비교하기 위한 Comparable 인터페이스 이해

 

[내용]

- Let's talk about 'Comparisons with generics' ...ㅠ

   → 제네릭 자료 구조나 객체 이용한 비교에 대한 이야기...를 한다고 하심...

 

- 오버라이드(Override)에 대한 설명

- 아래 두 코드를 비교한다고 가정하자

String one = "hello world";
String two = "hello world";

- 이때 비교는 equals 메소드를 이용함

if(one.equals(two))
	System.out.println("Same");

 

- 만약 one과 two를 Object로 형변환 후 equals 메소드로 비교한다면, 둘은 "메모리 주소"를 비교해서 같은지 확인하게 됨

Object o = one;
Object t = two;

if(o.equals(t))
	System.out.println("Same");

- 그럼 String형인 one과 two도 메모리 주소로 비교를 할까

   → one과 two는 같은 메모리 주소를 가지고 있지 않기 때문에 '둘은 같지 않다(false)'가 출력될 것으로 예상되겠지만

         실제 실행 결과는 '둘은 같다(true)'가 됨

   → equals 메소드는 객체를 비교할 땐 "메모리 주소"로 비교를 하지만, 문자열을 비교할 땐 "메모리 주소"로 비교하지 않음

 

 

- 그렇다면 이 equals 메소드는 어디에서 온 메소드일까

   → 바로 String 클래스에서 온 메소드

   → Object 클래스에 equals 메소드가 있는데 String 클래스가 Object 클래스를 상속 후 메소드를 오버라이드(Override)* 한 것

 

 

* 오버라이드(Override)?

→ 아래 글에서 복습하기

2021.11.16 - [2. 개발 공부/Java] - [공부 필기] Java 기본 공부하기 (16)

 

[공부 필기] Java 기본 공부하기 (16)

공부 중인 강의 : 윤성우 선생님, 윤성우의 열혈 Java 프로그래밍 강의. 링크 : https://cafe.naver.com/cstudyjava 윤성우의 프로그래밍 스터디그룹 [C/... : 네이버 카페 윤성우의 스터디 공간입니다. C와 JA

cinnamonc.tistory.com

 

 

 

- 여기에서 문제는 우리가 자료 구조를 만들었고, 다른 사람이 이 자료 구조를 사용할 수 있도록 할 때 발생함

- 아래의 코드를 보자

   → 누군가가 Person 이라는 클래스를 만들었고 그걸 가져와서 사용한다고 가정

Person p1 = new Person();
Person p2 = new Person();

- 이때 equals 메소드를 이용해서 두 객체를 비교한다면, 우리는 어떤 결과가 나올지 예측할 수 있을까

if(p1.equals(p2))
	System.out.println("Same");

- 정답은 "알수없음"

   → 이 코드만 봐서는 equals 메소드를 Person 클래스에서 오버라이드 했는지 안했는지 모르기 때문

   → 만약 Person 클래스에서 equals 메소드를 오버라이드 하지 않고

        Object 클래스 안에 정의되어 있는 equals를 그대로 사용한다면 "메모리 주소"를 비교하게 될 것임

        (Object 클래스에 그렇게 정의되어 있기 때문)

 

- 이런 문제를 해결하려면 어떻게 해야할까

   → euqals 메소드를 무조건 오버라이드 하도록 만들어야함

 

- 그리고 사실, 두 값이 같은지(equal) 비교하는 경우는 별로 없고 특정 값보다 크냐, 작냐를 비교하는 경우가 더 많음

   → 일례로 버블 정렬(bubble sort) 알고리즘만 보더라도 인접한 두 값을 비교해서 값이 더 큰 쪽을 더 뒤쪽으로 정렬함

 

- 그래서.. 어쨌든 우리는 equals 메소드 뿐만 아니라 값을 비교하는 다른 방법을 더 알아낼 필요가 있음

   → 그 방법 중 하나가 Comparable 인터페이스

 

 

- Comparable 인터페이스에 대한 설명

[그림1] Comparable 인터페이스 안에 있는 유일한 한 개의 추상메소드(compareTo)

 

- Comparable 인터페이스에는 유일하게, 딱 하나의 추상 메소드만 있는데, 그건 바로 compareTo

public interface Comparable<T> {
	public int compareTo(T o);
	// 매개변수 : 같은 자료형(T)의 객체
    // 반환값 : 정수(int)
    // 메소드명 : compareTo
}

 

- 우리는 이 compareTo 메소드를 Person 클래스에 정의(오버라이드)해서 두 개의 Person 객체를 비교할 수 있게됨

   → 마치 아래와 같이

public class Person implements Comparable<Person> {
	public String name;
	public int height;
	
	Person(String name, int height) {
		this.name = name;
		this.height = height;
	}
	
	@Override
	public int compareTo(Person p) {
    // 사람1과 사람2의 키(height)를 비교하고 있음
		if(this.height < p.height)
			return -1; // 이 사람의 키가 비교할 대상보다 작다면 -1를 반환
		else if(this.height == p.height)
			return 0; // 이 사람의 키가 비교할 대상과 같다면 0을 반환
		else
			return 1; // 이 사람의 키가 비교할 대상보다 크다면 1을 반환
	}
}

[그림2] 메인 메소드 실행 결과

- 물론 메인 메소드에서 아래와 같이 사용할 수도 있음

public class Main {
	public static void main(String args[]) {
		Person me = new Person("Kimsoy", 180);
		Person you = new Person("Lee", 180);
		
		if(((Comparable<Person>)me).compareTo(you) == 0)
        // me 인스턴스를 Comparable<Person>으로 형변환
			System.out.println("Same");
		else
			System.out.println("not Same");
	}
}

[그림3] 반환값으로 Same 혹은 not Same 출력하기

 

- 너무 코드에 대한 필기로만 치우쳤는데

- 어쨌든 우리가 자료구조를 설계할 때, compareTo 메소드를 사용하면서 신경 써야하는 점은 "compareTo라는 메소드가 있고, 이 메소드가 어떤 값이 더 큰지 작은지 비교를 해준다는 것"임

 

- 정리하자면, 우리는 자료 구조를 잘 설계하기만 하면 됨

   → 여기에서는 'me와 you를 비교해서 me의 키가 더 작으면 0보다 작은 수를 반환하도록 하고, 같으면 0을 반환하고, 크면 0보다 큰 수를 반환'하도록 설계하고 코드로 구현했음

- 그 후 알맞은 데이터가 들어올 것이고, compareTo 메소드는 그 데이터들을 규칙에 맞춰 (우리가 설계한대로) 알아서 작업을 해줄 것임

 

- 나중에 연결 리스트에서 이 방법을 사용할 예정임

   → contains 메소드를 함께 사용해서.

Comments