Java

Collections Framework

배열과 컬렉션즈 프레임워크

이전 시간에 배열에 대해서 공부했다. 배열은 연관된 데이터를 관리하기 위한 수단이었다. 그런데 배열에는 몇가지 불편한 점이 있었는데 그 중의 하나가 한번 정해진 배열의 크기를 변경할 수 없다는 점이다. 이러한 불편함을 컬렉션즈 프래임워크를 사용하면 줄어든다.

아래의 예를 보자.

package org.opentutorials.javatutorials.collection;

import java.util.ArrayList;

public class ArrayListDemo {

    public static void main(String[] args) {
		String[] arrayObj = new String[2];
		arrayObj[0] = "one";
		arrayObj[1] = "two";
		// arrayObj[2] = "three"; 오류가 발생한다.
		for(int i=0; i<arrayObj.length; i++){
			System.out.println(arrayObj[i]);
		}
		
		ArrayList al = new ArrayList();
		al.add("one");
		al.add("two");
		al.add("three");
		for(int i=0; i<al.size(); i++){
			System.out.println(al.get(i));
		}
	}

}

아래 코드처럼 배열은 그 크기를 한번 지정하면 크기보다 많은 수의 값을 저장할 수 없다.

String[] arrayObj = new String[2];
arrayObj[0] = "one";
arrayObj[1] = "two";
// arrayObj[2] = "three"; 오류가 발생한다.

하지만 ArrayList는 크기를 미리 지정하지 않기 때문에 얼마든지 많은 수의 값을 저장할 수 있다.

ArrayList al = new ArrayList();
al.add("one");
al.add("two");
al.add("three");

ArrayList는 배열과는 사용방법이 조금 다르다. 배열의 경우 값의 개수를 구할 때 .length를 사용했지만 ArrayList는 메소드 size를 사용한다. 또한, 특정한 값을 가져올 때 배열은 [인덱스 번호]를 사용했지만 컬렉션은 .get(인덱스 번호)를 사용한다.

for(int i=0; i<al.size(); i++){
	System.out.println(al.get(i));
}

그런데 ArrayList를 사용할 때 주의할 점이 있다. 위의 반복문을 아래처럼 바꿔보자.

for(int i=0; i<al.size(); i++){
	String val = al.get(i);
	System.out.println(val);
}

위의 코드는 컴파일 오류가 발생한다. ArrayList의 메소드 add의 입장에서는 인자로 어떤 형태의 값이 올지 알 수 없다. 그렇기 때문에 모든 데이터 타입의 조상인 Object 형식으로 데이터를 받고 있다. 예를들면 아래와 같은 모습일 것이다. (실제와는 다르다)

public boolean add(Object e) {

따라서 ArrayList 내에서 add를 통해서 입력된 값은 Object의 데이터 타입을 가지고 있고, get을 이용해서 이를 꺼내도 Object의 데이터 타입을 가지고 있게 된다. 그래서 위의 코드는 아래와 같이 바꿔야 한다.

for(int i=0; i<al.size(); i++){
	String val = (String)al.get(i);
	System.out.println(val);
}

get의 리턴값을 문자열로 형변환하고 있다. 원래의 데이터 타입이 된 것이다.

그런데 위의 방식은 예전의 방식이다. 이제는 아래와 같이 제네릭을 사용해야 한다.

ArrayList<String> al = new ArrayList<String>();
al.add("one");
al.add("two");
al.add("three");
for(int i=0; i<al.size(); i++){
	String val = al.get(i);
	System.out.println(val);
}

제네릭을 사용하면 ArrayList 내에서 사용할 데이터 타입을 인스턴스를 생성할 때 지정할 수 있기 때문에 데이터를 꺼낼 때(String val = al.get(i);) 형변환을 하지 않아도 된다.

컬렉션즈 프래임워크란?

그럼 이제부터 컬렉션즈 프래임워크가 무엇인가 본격적으로 알아보자. 컬렉션즈 프래임워크라는 것은 다른 말로는 컨테이너라고도 부른다. 즉 값을 담는 그릇이라는 의미이다. 그런데 그 값의 성격에 따라서 컨테이너의 성격이 조금씩 달라진다. 자바에서는 다양한 상황에서 사용할 수 있는 다양한 컨테이너를 제공하는데 이것을 컬렉션즈 프래임워크라고 부른다. ArrayList는 그중의 하나다.

위의 그림은 컬렉션즈 프래임워크의 구성을 보여준다. Collection과 Map이라는 최상위 카테고리가 있고, 그 아래에 다양한 컬렉션들이 존재한다. 그럼 구체적인 컬렉션즈 프래임워크 클래스들을 살펴보자.

ArrayList를 찾아보자. Collection-List에 속해있다. ArrayList는 LIst라는 성격으로 분류되고 있는 것이다. List는 인터페이스이다. 그리고 List 하위의 클래스들은 모두 List 인터페이스를 구현하기 때문에 모두 같은 API를 가지고 있다. 클래스의 취지에 따라서 구현방법과 동작방법은 다르지만 공통의 조작방법을 가지고 있는 것이다. 익숙한 ArrayList를 바탕으로 나머지 컬렉션들의 성격을 파악해보자.

List와 Set의 차이점은 List는 중복을 허용하고, Set은 허용하지 않는다.

package org.opentutorials.javatutorials.collection;

import java.util.ArrayList;
import java.util.HashSet;

import java.util.Iterator;

public class ListSetDemo {

    public static void main(String[] args) {
		ArrayList<String> al = new ArrayList<String>();
		al.add("one");
		al.add("two");
		al.add("two");
		al.add("three");
		al.add("three");
		al.add("five");
		System.out.println("array");
		Iterator ai = al.iterator();
		while(ai.hasNext()){
			System.out.println(ai.next());
		}
		
		HashSet<String> hs = new HashSet<String>();
		hs.add("one");
		hs.add("two");
		hs.add("two");
		hs.add("three");
		hs.add("three");
		hs.add("five");
		Iterator hi = hs.iterator();
		System.out.println("\nhashset");
		while(hi.hasNext()){
			System.out.println(hi.next());
		}
	}

}

결과는 아래와 같다.

array
one
two
two
three
three
five

hashset
two
five
one
three

우선 값을 가져오는 방법이 조금 달라졌다. (ArrayList에서도 이 방법을 사용할 수 있다)

Iterator ai = al.iterator();
while(ai.hasNext()){
	System.out.println(ai.next());
}

메소드 iterator는 인터페이스 Collection에 정의되어 있다. 따라서 Collection을 구현하고 있는 모든 컬렉션즈 프레임웍크는 이 메소드를 구현하고 있음을 보증한다. 메소드 iterator의 호출 결과는 인터페이스 iterator를 구현한 객체를 리턴한다. 인터페이스 iterator는 아래 3개의 메소드를 구현하도록 강제하고 있는데 각각의 역할은 아래와 같다.

  • hasNext
    반복할 데이터가 더 있으면 true, 더 이상 반복할 데이터가 없다면 false를 리턴한다.
  • next
    hasNext가 true라는 것은 next가 리턴할 데이터가 존재한다는 의미다. 

이러한 기능을 조합하면 for 문을 이용하는 것과 동일하게 데이터를 순차적으로 처리할 수 있다.

그럼 본론으로 돌아와서 Set과 List의 차이를 짚어보자. 위의 결과를 통해서 알 수 있는 것처럼 Set는 중복을 허용하지 않고 순서가 없지만, List는 중복을 허용하고 저장되는 순서가 유지된다는 것을 알 수 있다. 이러한 특징을 고려해서 컬렉션을 선택해야 한다. 그럼 Set에 대해서 조금 더 알아보자.

Set

Set은 한국어로 집합이라는 뜻이다. 여기서의 집합이란 수학의 집합과 같은 의미다. 수학에서의 집합도 순서가 없고 중복되지 않는 특성이 있다는 것이 기억날 것이다. (기억나지 않아도 상관없다) 수학에서 집합은 교집합(intersect), 차집합(difference), 합집합(union)과 같은 연산을 할 수 있었다. Set도 마찬가지다.

이 내용은 수학적 지식을 요구하지 않는다. 겁내지 말자. (프로그래밍과 수학)

아래와 같이 3개의 집합 hs1, hs2, hs3이 있다고 하자. h1은 숫자 1,2,3으로 이루어진 집합이고, h2는 3,4,5 h3는 1,2로 구성되어 있다. set의 API를 이용해서 집합 연산을 해보자.

package org.opentutorials.javatutorials.collection;

import java.util.ArrayList;
import java.util.HashSet;

import java.util.Iterator;

public class SetDemo {

    public static void main(String[] args) {
		HashSet<Integer> A = new HashSet<Integer>();
		A.add(1);
		A.add(2);
		A.add(3);
		
		HashSet<Integer> B = new HashSet<Integer>();
		B.add(3);
		B.add(4);
		B.add(5);
		
		HashSet<Integer> C = new HashSet<Integer>();
		C.add(1);
		C.add(2);
		
		System.out.println(A.containsAll(B)); // false
		System.out.println(A.containsAll(C)); // true
		
		//A.addAll(B);
		//A.retainAll(B);
		//A.removeAll(B);
		
		Iterator hi = A.iterator();
		while(hi.hasNext()){
			System.out.println(hi.next());
		}
	}

}

부분집합 (subset)

System.out.println(A.containsAll(B)); // false
System.out.println(A.containsAll(C)); // true

합집합(union)

A.addAll(B);

교집합(intersect)

A.retainAll(B);

차집합(difference)

A.removeAll(B);

 

Map

이번에는 Map 컬렉션에 대해서 알아보자. Map 컬렉션은 key와 value의 쌍으로 값을 저장하는 컬렉션이다. 아래 코드를 보자.

package org.opentutorials.javatutorials.collection;

import java.util.*;

public class MapDemo {

    public static void main(String[] args) {
		HashMap<String, Integer> a = new HashMap<String, Integer>();
		a.put("one", 1);
		a.put("two", 2);
		a.put("three", 3);
		a.put("four", 4);
		System.out.println(a.get("one"));
		System.out.println(a.get("two"));
		System.out.println(a.get("three"));
		
		iteratorUsingForEach(a);
		iteratorUsingIterator(a);
	}
	
	static void iteratorUsingForEach(HashMap map){
		Set<Map.Entry<String, Integer>> entries = map.entrySet();
		for (Map.Entry<String, Integer> entry : entries) {
		    System.out.println(entry.getKey() + " : " + entry.getValue());
		}
	}
	
	static void iteratorUsingIterator(HashMap map){
		Set<Map.Entry<String, Integer>> entries = map.entrySet();
		Iterator<Map.Entry<String, Integer>> i = entries.iterator();
		while(i.hasNext()){
			Map.Entry<String, Integer> entry = i.next();
			System.out.println(entry.getKey()+" : "+entry.getValue());
		}
	}

}

Map에서 데이터를 추가할 때 사용하는 API는 put이다. put의 첫번째 인자는 값의 key이고, 두번째 인자는 key에대한 값이다. key를 이용해서 값을 가져올 수 있다.

System.out.println(a.get("one"));

이것이 Map의 가장 기본적인 사용법이다. 그럼 Map에 저장된 데이터를 열거할 때는 어떻게 해야할까?

Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String, Integer> entry : entries) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

메소드 entrySet은 Map의 데이터를 담고 있는 Set을 반환한다. 반환한 Set의 값이 사용할 데이터 타입은 Map.Entry이다. Map.Entry는 인터페이스인데 아래와 같은 API를 가지고 있다.

  • getKey
  • getValue

위의 API를 이용해서 Map의 key, value를 조회할 수 있다.

앞서 Set이 수학의 집합을 프로그래밍적으로 구현한 것이라고 언급했다. map은 수학의 함수를 프로그래밍화한 것이다. 수학의 함수가 "정의역과 공역 원소들 사이의 단가 대응의 관계"라는 의미를 이해하고 있는 사람이라면 Map의 key와 value의 관계가 함수의 정의역과 공역의 관계와 같다는 것을 이해할 수 있을 것이다.  함수에 대한 이해가 없다면 이 내용은 몰라도 된다. 하지만 프로그래밍을 하게 되면 수학적인 지식들을 매우 구체적으로 경험할 수 있기 때문에 프로그래밍은 수학에 대한 좋은 실습 도구라고 할 수 있다. 수학이 너무 추상적이라서 배움에 어려움이 있는 독자라면 프로그래밍에 익숙해진 후에 수학공부를 시작해보자. 프로그래밍의 많은 장치들이 수학적인 장치들을 빌려온 것임을 알 수 있을 것이고, 수학이 보다 구체적으로 다가올 것이다.

데이터 타입의 교체

컬렉션을 사용할 때는 데이터 타입은 가급적 해당 컬렉션을 대표하는 인터페이스를 사용하는 것이 좋다. 이전 예제의 12행의 내용은 아래와 같다.

HashMap<String, Integer> a = new HashMap<String, Integer>();

이것을 아래와 같이 수정한다. HashMap은 Map 인터페이스를 구현하기 때문에 변수 a의 데이터 타입으로 Map을 사용할 수 있다.

Map<String, Integer> a = new HashMap<String, Integer>();

어떤 필요에 의해서 컬렉션을 HashMap에서 HashTable로 바꾸고 싶다면 아래와 같이 수정하면 된다.

Map<String, Integer> a = new Hashtable<String, Integer>();

정렬

컬렉션을 사용하는 이유 중의 하나는 정렬과 같은 데이터와 관련된 작업을 하기 위해서다. 정렬하는 법을 알아보자. 패키지 java.util 내에는 Collections라는 클래스가 있다. 이 클래스를 사용하는 법을 알아보자.

package org.opentutorials.javatutorials.collection;

import java.util.*;

class Computer implements Comparable{
    int serial;
	String owner;
	Computer(int serial, String owner){
		this.serial = serial;
		this.owner = owner;
	}
	public int compareTo(Object o) {
		return this.serial - ((Computer)o).serial;
	}
	public String toString(){
		return serial+" "+owner;
	}
}

public class CollectionsDemo {
	
	public static void main(String[] args) {
		List<Computer> computers = new ArrayList<Computer>();
		computers.add(new Computer(500, "egoing"));
		computers.add(new Computer(200, "leezche"));
		computers.add(new Computer(3233, "graphittie"));
		Iterator i = computers.iterator();
		System.out.println("before");
		while(i.hasNext()){
			System.out.println(i.next());
		}
		Collections.sort(computers);
		System.out.println("\nafter");
		i = computers.iterator();
		while(i.hasNext()){
			System.out.println(i.next());
		}
	}

}

결과

before
500 egoing
200 leezche
3233 graphittie

after
200 leezche
500 egoing
3233 graphittie

클래스 Collectors는 다양한 클래스 메소드를 가지고 있다. 메소드 sort는 그 중의 하나로 List의 정렬을 수행한다. 다음은 sort의 시그니처다.

public static <T extends Comparable<? super T>> void sort(List<T> list)

sort의 인자인 list는 데이터 타입이 List이다. 즉 메소드 sort는 List 형식의 컬렉션을 지원한다는 것을 알 수 있다. 인자 list의 제네릭 <T>는 coparable을 extends 하고 있어야 한다. Comparable은 인터페이스인데 이를 구현하고 있는 클래스는 아래 메소드를 가지고 있어야 한다.

아래의 메소드는 이러한 제약 조건을 준수하기 위해서 구현한 메소드다.

public int compareTo(Object o) {
	return this.serial - ((Computer)o).serial;
}

메소드 sort를 실행하면 내부적으로 compareTo를 실행하고 그 결과에 따라서 객체의 선후 관계를 판별하게 된다.

이렇게 해서 컬렉션즈 프레임워크에 대한 수업을 마무리 하겠다. 컬렉션즈 프레임워크는 효율적인 에플리케이션을 구축하기 위해서 매우 중요한 내용이다. 그런데 컬렉션은 단순히 사용법을 이해하는 것으로는 부족하고, 소위 알고리즘이나 자료구조(data structure)라고 불리는 분야에 대한 충분한 이해가 필요하다. 컬렉션즈 프레임워크는 이러한 분야의 성취를 누구나 쉽게 사용할 수 있도록 제공되는 일종의 라이브러리라고 할 수 있기 때문이다.

참조

댓글

댓글 본문
작성자
비밀번호
  1. 소트라니
    9/9 동영상에서 sort() 원리를 잘 모르겠네요.

    sort() 를 사용하기 위해선 정렬 당하는 객체들(Array List 내 computer들)이 Comparable 상속받고 public int compareTo(Object o) 메소드 내용까지 정의되어져 있어야 한다는 건 알겠는데, 그래서 그게 어떻게 동작하는지
    잘 모르겠어서 열심히 찾아보고있는 중입니다 ㅠㅠ
  2. 드디어끝
    잘들었습니다 감사합니다
  3. ljn425
    수업 정말 잘들었습니다. 감사 또 감사합니다.
  4. 너무 험난한 길이었어요.
    이 글을 김경준에게 바칩니다.
  5. 내일도
    수업잘들었습니다 정말 감사합니다
  6. 김승진
    String은 기본적인 데이터 타입이 아니고 클래스입니다. 기본적인 타입을 쓰기위해 Wrapper클래스(Int,Double 등...)을 넣어 주어야 됩니다.
    대화보기
    • 갓고잉
      제네릭 안에 데이터타입을 설정할때 그값이 기본적인 데이터타입 형식은 안된다고 들은거 같은데 첫번째 동영상에서는Araylist이거 쓸때 String타입을 쓰네요?
    • 1004-1
      set 은 기본적으로 정렬이 되어 들어가는것으로 알고 있습니다.
      대화보기
      • 시루
        으으으... 많이 쓰면 적응 되겟죠?
      • 툰아미
        이클립스의 디버깅 기능을 사용하면 되요. 소스 코드에서 Breaking Point 설정하시고 F11키를 누르면 디버깅 모드로 넘어가요. 디버깅 모드에서 F5 키를 이용하면 세세하게 흐름을 따라가기는 하지만, 상속이나 구현을 여러 번 따라가게 되고, step이 되게 많을 거에요. F6 키를 이용하면 세세하게 로직을 따라가지 않고 변수들에 들어가는 값만 간단하게 확인할 수 있어요. 자세한 건 이클립스 디버깅 방법을 찾아보세요.
        대화보기
        • 툰아미
          잘은 모르겠지만, HashSet은 해싱 기법을 이용하기 때문이 아닐까 싶네요. 해시 코드 값이 동일하게 나오기 때문에 중복 저장이 불가능하고, 저장 순서는 유지하지 않지만 출력 순서가 일정하지 않을까 싶네요.
          이클립스에서 디버깅하면서 본 HashSet의 table 내용을 확인해 보세요. 저장된 데이터의 table 인덱스 번호나 해시 코드 값이 항상 똑같이 나올 걸요?
          대화보기
          • ㅇㅇ
            오늘 처음 강의 봤는데 정말 도움이 많이 되었습니다. 감사합니다.
          • 멋개
            항상 감사합니다!
          • JustStudy
            고맙습니다
          • 감사합니다.ㅇ
          • 김트라슈
            흐미.. 중요한 내용이라서 그런지 굉장히 어렵네요.. 감사합니다.
          • nobodj
            질문이 있습니다. set이 꺼내지는 순서에 규칙이 있나요? HashSet에 데이터를 전달하고 iterator()을 통해 꺼내면, 항상 같은 순서인대요. 데이터 전달 순서를 바꾸어도 나오는 순서는 똑같네요...무슨 룰이 있는거 같기도 하고요. 혹시 아시는 분 답변 좀 부탁드려요. :) I love you all~
          • 오빠는다르다
            감사합니다!!!!!!
          • 레니타키
            프레임웍은 따로 알아야 될게 많네요 . 좋은 수업 감사합니다.
          • 강의를 볼수있었음에 감사를 드립니다.
            그리고 어려운부분들이 있네요 ㅎㅎㅎ
            아마도 익숙해 질려면 시간과 땀이라는 조미료를 좀 넣어야 겠죠

            능숙해지는 그날을 꿈꾸는것에 대한 모티브를 제공해주신 egoing님께 다시 고맙다는 말씀을
            전하고 싶네요.
            혹여 막막한 부분에대한 교과서적인 역활의 강의라 저는 개인적으로 생각하며

            새해 복 많이 받으시길 바랍니다.
          • Beluga
            제가 알기론..
            Java 설치 폴더에 있는
            src.zip 안에.. 모든 라이브러리의 소스코드가 있습니다.

            그걸 원하시는 폴더에 복사하셔서
            압축 푸시고
            찾아보시면
            실제 어떻게 구현되어 있는지 보실 수 있을 거예요.
            대화보기
            • 박첩구드
              어렵네요 ㅠ 책을 보면서 더 심층적으로 공부해야겠어요 감사합니다!
            • ¥oungseok
              5번쨰 동영상에서
              Collection Interface를
              AbstractCollection이라는 class에서 구현하고 있다고 하셨는데
              그 내용을 소스코드로 자세히 볼수있는 곳이 있나요?
              Interface는 껍데기일 뿐이고 AbstractCollection에서 구현이 되었다면
              그 내용이 있을텐데...

              ex)Iterator같은 것이 실제로 어떤 소스코드에 의해서 동작하는지 확인하고 싶어서...
            • 박민호
              아하 감사합니다 이고잉님. 항상 감사한 마음으로 강의 듣고 있습니다.^^
            • egoing
              클래스는 사용자가 직접 데이터를 만든 것이라고도 할 수 있습니다. 맥락에 따라서 아마도 다른 표현을 쓰고 있는게 아닐까 싶네요. 수업을 만든지 좀 오래 되어서 :)
              대화보기
              • 박민호
                클래스랑 데이터 타입이랑 같은건가요? 왜자꾸
                제너릭 부분에서 설명해줄때는 데이터 타입을 지정해주는거라면서 설명해주셧으면서
                여기서는 왜 클래스라고 하는지 이해가 안되네용..
                List<Computer>computers = new ArrayList<computer>();
                이부분이요..
              • cocohodu
                좋은강의 감사합니다
              • June Ko
                잘 봤습니다. C와 C++을 제외하고 처음 배우는 언어인대 알기쉽게 잘 설명해주셨내요.
              • zelaw
                잘 봤습니다. 아쉽게도 정말 기초적인 설명만 있네요...
                콜렉션프레임워크가 중요한 만큼 자세한 설명 해 주시면 감사하겠습니다.
                ㅋㅋ
                같은 남자인데도 목소리가 매력적입니다. ㅋㅋ
              • Vanillasea
                네 감사합니다. ㅎㅎ
                자료구조 공부 더 해야겠어요. 전 초보자인데
                egoing님 수업을 듣다보니 개념이해가 너무 잘되서 거기까지 갔나봐요. ㅋㅋ
                egoing님 수업 열심히 듣고 있습니당. 고맙습니당:)
                대화보기
                • egoing
                  그 이유를 말씀 드리는 것은 지금 단계에서는 조금 벅차고요. 아래 수업을 통해서 나중에 이해할 수 있습니다. 지금 보시는 것은 추천하지 않고요.

                  http://opentutorials.org......335

                  하지만 간단히 말씀 드리면, iterator 패턴을 사용해서 구현을 해두면 내부적으로 반복적인 작업을 위해서 사용하는 방법을 바꾸더라도, 그것을 사용하는 쪽에서는 그 동작방법을 바꿀 필요가 없습니다.
                  대화보기
                  • Vanillasea
                    iterator와 while을 사용해 값을 출력한 것과 for문을 이용해 값을 출력하면 동일한 값이 나옵니다. 두 가지 방법 모두 결과값은 같은데 분명 차이점이 있을것 같아요. 육안으로는 차이점을 모르겠는데 큰 차이점은 무엇일까요?, 또 Iterator라는 인터페이스 타입의 변수에 iterator라는 메소드로 객체를 또 다시 생성해서 출력하는 것이 차이라면 왜 이렇게 어렵게 출력해야하는건가요? for문으로 하면 그만인데요, 객체 생성해서 출력 해낸다는 이유가 전부인가요?
                    그리고, 사실, Iterator타입의 변수라는건 이해 되는데, 메소드를 구현할때 객체가 생성되서 그 객체를 Iterator 타입의 변수에 넣는다는 개념이 어렵네요. 혹시 관련 정보나 아시는 분은 알려주시면 감사하겠습니다. 나름 구글을 다 돌려봤는데 개념파익할 수 있는 글 찾기가 어렵네요.
                  • Caesar
                    제 질문이 잘못되었나보네요. 저는 정확히 소스코드 내에 어떠한 메소드에 의한 건지가 궁금해서 질문을 올렸어요 어떠한 메소드가 음수 값을 받는 지 등등, 정확하고 구체적인 코드가 궁금했을 뿐입니다. 그래도 답변 달아주셔서 감사합니다.
                    대화보기
                    • 이고잉님짱
                      저희 학교 교수님으로 오셨으면 좋겠어요.
                      큰 흐름을 잡아주시니 이게 왜 이렇게 쓰이는지도 이해가 척척~

                      다만 아쉬웠던점은 깊이가 얇아서 나머진 혼자 공부해야 한다는 점인데
                      이고잉님께서 큰 흐름을 잡아주시니 남은 부분은 그래도 쉽게 될것 같습니다.

                      감사합니다^^
                    • 금도끼은도끼
                      음 정확한 답인지는 모르겠지만 제가 아는 한도에서 설명드릴게요..
                      public int compareTo(Object o) {
                      return this.serial - ((Computer)o).serial;
                      }
                      인자로 전달된 값이 작다면 양수
                      인자로 전달된 값이 크다면 음수
                      인자로 전달된 값이 같다면 0을 반환하겠지요
                      이건 단지 값의 크기를 비교한거에요
                      우리가 입력값의 크기만 비교해놓으면 되구요(juyul님 댓글처럼 리턴값에 마이너스를 붙이면 반대크기가 되겠죠)
                      그값을 쓸때는
                      프로그래머가 오름차순으로 출력해라 하구 프로그램을 짜면 =>Collections.sort() ;
                      오름차순으로 출력되겠지요 ,반대로 내림차순으로 출력하라구하면 내림차순으로 출력될거구요.
                      따라서 egoing님의 설명처럼
                      sort를 실행하면 내부적으로 compareTo를 실행하고 그 결과에 따라서 객체의 선후 관계를 판별
                      대화보기
                      • 금도끼은도끼
                        정말 설명을 넘잘하시네요

                        책은안봐봣지만 정말 자바동영상은 넘쉽게 설명을 잘해놓으셨네요.

                        만드시느라 얼마나 많은 노력을 하셨을가 감히 짐작해봅니다..

                        정말 감사합니다 (__)
                      • Caesar
                        정말 계속 API도 찾아보고 소스코드도 살펴봤지만 못찾아서 이렇게 글을 남깁니다.

                        정렬(9/9) 부분에서
                        Collections.sort(computers);를 작동시키면
                        computer 클래스로 값이 이동해서
                        public int compareTo(Object o) {
                        return this.serial - ((Computer)o).serial;
                        }
                        까지 된다음에 sorting 된다고 말씀해주셨는데.
                        compareTo 다음에는 도대체 그 return 값이 어디로 가는 거죠?
                        제 예상에는 collections 클래스에 if 문이 있어야지 sorting이 되어
                        오름차순으로 정렬되는 거 같은데, 도통 그 조건문을 못찾겠어서요.
                        혹 찾아주시면 링크 및 소스코드의 setnumber를 알려주실수 있나요?
                        너무 궁금합니다.
                        정말 API, 소스코드 다 찾아보고 결국 이렇게 댓글을 남김니다. 도움을 부탁드립니다.
                      • bepositive1223
                        아... 쭈~욱 다봤지만... 집중력이 흐려지네요;;;

                        조금씩 조금씩 계속봐야지요.....

                        이젠 자료구조 공부하러`~ ㅋ


                        감사합니다 이고잉님~ ㅋㅋ
                      • cccc
                        멋진 강의 감사합니다! 정말 훌륭했어요.
                      • 사그루
                        이 부분을 배우지 못하고 JSP로 넘어가서 한참을 헤매였네요;
                        뭘 모르는지도 모르는 상태로 그냥 다 몰라서, 뭘 공부해야 할지조차 감이 안왔었는데-
                        역시 기본기가 제일 중요한 것 같습니다!
                        좋은 강의 감사히 잘들었습니다.
                        직관적으로 마지막 메소드들의 엉켜있는 사용이 팍! 이해가 되지는 않지만,
                        반복해서 보다보면 언젠가는 아하, 할 날이 오리라 믿고!^^
                        10번 보기로!
                      • 아무개
                        감사합니다~!!
                      • 도움이 많이되었습니다 ! 이고잉님 짱짱맨
                      • jeyul
                        마지막 예제에서 Computer 클래스의 compareTo 메소드에 리턴값의 부호를 바꿔보자.

                        return -(this.serial - ((Computer)o).serial);

                        부호가 반대로 리턴되기 때문에 아마도 정렬 순서가...
                        실행결과는 직접 확인 해보세요.^^
                      • 타조알
                        잘봤습니다~ 너무 잘 가르쳐주셔서 감사하구요~
                        앞으로도 종종 와서 다시 봐야할 부분이 있을 것 같아요~
                        정말 감사드립니다.
                      • 인랑
                        완주 했습니다.

                        끝까지 포기하지 않고 듣다 보니 어느새 완주 했네요.
                        감사합니다.
                      • hehypapa
                        완주했어요~!!!
                        이고잉님 고생많으셨습니다~!
                        ㅎㅎㅎ
                      • 샤핀
                        JAVA강좌 재밌게 잘봤습니다 ^^.
                        이고잉님의 노고에 감사드립니다 (__)
                      • 초초보
                        감사합니다. 강의 잘 봤습니다. 꾸벅
                      • 너부리
                        정말 훌륭한 온라인강의 입니다. 몇년째 프로그래밍 공부하다 매번 포기했는데 이고잉님 강의는 중간에 끊을 수 없는 중독성이 ...ㅎㅎ
                        앞으로도 좋은 강의 부탁드리고요. 오프라인 강의 기회도 많이 있었으면 합니다. 수고하셨습니다.
                      • Han ByungHak
                        좋은 강의 잘 시청했습니다. 감사합니다.
                      버전 관리
                      egoing
                      현재 버전
                      선택 버전
                      graphittie 자세히 보기