hashtable

hashtable은 Map을 상속받아 key,value 형태를 가지게 된다.
key,value는 한쌍으로 사용되며 key로 식별용 값, value는 사용할 값을 넣는 식이다.

HashMap과 상당히 비슷한데 완전 똑같은 것은 아니므로 비교해 보자면

  1. HashTable은 동기화가 되어 있으나, HashMap은 동기화 되어있지 않다.

  2. HashTable은 key, value에 null값을 허용하지 않지만 HashMap은 허용한다.

     Hashtable 안에 값 넣기
     Hashtable.put(key, value);
    
     Hashtable 안의 값 가져오기
     Hashtable.get(key);
    
     Hashtable 안의 값 바꾸기
     Hashtable.replace(key, value);
    
     Hashtable 안의 내용 삭제하기
     Hashtable.remove(key);
    
     Hashtable의 크기 0인지 확인하기
     Hashtable.isEmpty();
     
     Hashtable 사이즈 확인하기
     Hashtable.size();
     
     Hashtable 안에 특정 Key, Value 들었는지 확인하기
     Hashtable.containsKey(key);
     Hashtable.containsValue(value);
    
     Hashtable 안에 들어있는 전체 Key 확인하기
     Hashtable.keySet();
     import java.util.Hashtable;
    

예제

public class HashTableExample {

    public static void main(String[] args) {
        Hashtable<Integer, String> ht = new Hashtable<Integer, String>();
        ht.put(0, "철수");
        ht.put(1, "영희");
        ht.put(2, "영수"); // Hashtable에 값 삽입
        ht.replace(2, "수철"); // Hashtable 값 바꾸기
        ht.remove(2); // Hashtable 값 삭제

        for(int i = 0; i<ht.size(); i++) {
            System.out.println(ht.get(i)); // Hashtable 값 출력
        }
        
        System.out.println("Hashtable 크기 : " + ht.size());
        System.out.println("Hashtable key 확인 : " + ht.containsKey(2));
        System.out.println("Hashtable value 확인 : " + ht.containsValue("수철"));
        System.out.println("Hashtable 크기 0인지 확인 : " + ht.isEmpty());
        System.out.println("Hashtable 전체 Key 확인 : " + ht.keySet());
        
    }

}
결과값
철수
영희
Hashtable 크기 : 2
Hashtable key 확인 : false
Hashtable value 확인 : false
Hashtable 크기 0인지 확인 : false
Hashtable 전체 key 확인 : [1, 0]    

Comment and share

new 연산자

클래스 객체변수 = new 클래스();

인스턴스를 생성할 때 사용하는 코드이며 객체 변수가 실제 데이터가 아닌 참조 값을 갖는다는 내용이 포함되어 있다.
new는 클래스 타입의 인스턴스를 생성해주는 역할을 담당한다.
new연산자를 통해 메모리(Heap 영역)에 데이터를 저장할 공간을 할당받고 그 공간의 참조값을 객체에게 반환하여 주고 이어서 생성자를 호출하게 된다. 인스턴스를 핸들하기 위해서는 new 연산자를 통해 참조값을 저장한 객체로만 접근이 가능하다.

클래스      객체변수    =    new        클래스();
자료형      참조값저장     메모리할당   생성자호출

Comment and share

VO(Value Object)

  • 불변성 - 수정자(Setter)가 없다.
  • 값 동등성 - 내부 값 동등성 검사
  • 자가 유효성 검사 - 생성자에서 validate

불변성

Value Object는 불변이다.
불변이라는 뜻은 한번 생성되면 이후 내부 값을 바꿀 수 없음을 의미한다. 즉 setter를 허용하지 않는다는 말이다.

Value Object는 코드의 다른 부분에서 수정되지 않기 때문에 Reference로 공유할 수 있다. 이것은 코드의 복잡성과 부하를 극적으로 감소시킨다. 또한 Multi-thread환경에서 그 이점이 뚜렷해진다.

# 생성된 이후에는, 수정자(setter)를 통해 수정되지 않습니다. 
final class Number{

        private int number;
        
        public Number(int number){
                this.number = number;
        }
}

값 동등성

‘동일성’ 식별자를 기반으로 객체가 같은지를 판단할 수 있는 성질
‘동등성’ 상태를 이용해 두 값이 같은지 판단할 수 있는 성질

자가 유효성 검사

생성자가 주입될 때 값의 유효성을 확인해야 한다. 유효하지 않으면 의미있는 에러를 표출한다. 이는 객체의 인스턴스에 더이상 if가 없음을 의미한다. 모든 유효성 검사는 생성 시간에 이루어진다.

이러한 강제 유효성 검사는 의미 있고 명시적인 방법으로 도메인 제약 조건을 표현하는데도 유용하다.

Comment and share

List 컬렉션

List 컬렉션은 배열과 비슷하게 객체를 인덱스로 관리한다. 배열과의 차이점은 저장용량이 자동으로 증가하며, 객체를 저장할 때 자동 인데그삭 부여된다는 것이다. 그리고 추가, 삭제, 검색을 위한 다양한 메소드들이 제공된다.

List 컬렉션은 객체 자체를 저장하는 것이 아니라 객체의 번지를 참조한다. 그렇기 때문에 동일한 객체를 중복 저장할 수 있는데, 이 경우 동일한 번지가 참조된다. null도 저장이 가능하며, 이 경우 해당 인덱스는 객체를 참조하지 않는다.

ArrayList 클래스

ArrayList클래스는 가장 많이 사용되는 컬렉션 클래스 중 하나이다.
내부적으로 배열을 이용하여 요소를 저장한다.

ArrayList클래스는 배열을 이용하기 때문에 인덱스를 이용해 배열요소에 빠르게 접근할 수 있다.
하지만 배열은 크기를 변경할 수 없는 인스턴스이므로, 크기를 늘리기 위해서는 새로운 배열을 생성하고 기존의 요소들을 옮겨야 하는 복잡한 과정을 거쳐야 한다.
물론 이 과정은 자동으로 수행되지만, 요소의 추가 및 삭제 작업에 걸리는 시간이 매우 길어지는 단점을 가지게 된다.

ArrayList<Integer> arrList = new ArrayList<Integer>();

// add() 메소드를 이용한 요소의 저장
arrList.add(40);
arrList.add(20);
arrList.add(30);
arrList.add(10);

// for 문과 get() 메소드를 이용한 요소의 출력
for (int i = 0; i < arrList.size(); i++) {
    System.out.print(arrList.get(i) + " ");
}

// remove() 메소드를 이용한 요소의 제거
arrList.remove(1);

// Enhanced for 문과 get() 메소드를 이용한 요소의 출력
for (int e : arrList) {
    System.out.print(e + " ");
}

// Collections.sort() 메소드를 이용한 요소의 정렬
Collections.sort(arrList);

// iterator() 메소드와 get() 메소드를 이용한 요소의 출력
Iterator<Integer> iter = arrList.iterator();
while (iter.hasNext()) {
    System.out.print(iter.next() + " ");
}

// set() 메소드를 이용한 요소의 변경
arrList.set(0, 20);

for (int e : arrList) {
    System.out.print(e + " ");
}

// size() 메소드를 이용한 요소의 총 개수
System.out.println("리스트의 크기 : " + arrList.size());

결과값

40 20 30 10 
40 30 10
10 30 40 
20 30 40
리스트의 크기 : 3

LinkedList 클래스

LinkedList클래스는 ArrayList클래스가 배열을 이용하여 요소를 저장함으로써 발생하는 단점을 극복하기 위해 고안되었다.
LinkedList클래스는 내부적으로 연결리스트를 통해 요소를 저장한다.

배열은 저장된 요소가 순차적으로 저장된다.
하지만 연결리스트는 저장된 요소가 비순차적으로 분포되며, 이러한 요소들 사이를 링크로 연결하여 구성한다.
다음 요소를 가리키는 참조만을 가지는 연결 리스트를 단일 연결리스트라고한다.

이러한 단일 연결리스트는 요소의 저장과 삭제 작업이 다음요소를 가리키는 참조만 변경하면 되므로, 아주 빠르게 처리된다.
하지만 단일 연결리스트는 현재 요소에서 이전요소로 접근하기가 매우 어렵다.

따라서 이전 요소를 가리키는 참조도 가지는 이중 연결 리스트가 좀더 많이 사용된다.

LinkedList클래스도 이중 연결 리스트를 내부적으로 구현한 것이다.
또한, LinkedList클래스 역시 List인터페이스를 구현하므로, ArrayList클래스와 사용할 수 있는 메소드가 거의 같다.

LinkedList<String> lnkList = new LinkedList<String>();

// add() 메소드를 이용한 요소의 저장
lnkList.add("넷");
lnkList.add("둘");
lnkList.add("셋");
lnkList.add("하나");

// for 문과 get() 메소드를 이용한 요소의 출력
for (int i = 0; i < lnkList.size(); i++) {
    System.out.print(lnkList.get(i) + " ");
}

// remove() 메소드를 이용한 요소의 제거
lnkList.remove(1);

// Enhanced for 문과 get() 메소드를 이용한 요소의 출력
for (String e : lnkList) {
    System.out.print(e + " ");
}

// set() 메소드를 이용한 요소의 변경
lnkList.set(2, "둘");

for (String e : lnkList) {
    System.out.print(e + " ");
}

// size() 메소드를 이용한 요소의 총 개수
System.out.println("리스트의 크기 : " + lnkList.size());

결과값
넷 둘 셋 하나
넷 셋 하나
넷 셋 둘
리스트의 크기 : 3

Vector 클래스

Vector 클래스는 ArrayList클래스와 같은 동작을 수행하는 클래스이다. 현재의 Vector클래스는 ArrayList클래스와 마찬가지로 List인터페이스를 상속받는다.
따라서 Vector클래스에서 사용할 수 있는 메소드는 ArrayList클래스에서 사용할 수 있는 메소드와 거의 같다.
하지만 현재 기존 코드와의 호환성을 위해서 남아있으므로, Vector클래스보다는 ArrayList클래스를 사용하는 것이 좋다.

Comment and share

Collection Framwork

자바에서 컬렉션 프레임워크란, 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미한다. 다시말해 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것이다.

이러한 컬렉션 프레임워크는 자바의 인터페이스를 사용하여 구현된다.

컬렉션 프레임워크긔 핵심 인터페이스

크게 3가지 타입으로 나누어 핵심이 되는 주요 인터페이스를 정의했다.

  1. List
  2. Set
  3. Map

여기서 List와 Set 인터페이스의 공통점을 뽑아내어 새로운 인터페이스인 Collection을 추가로 정의하였다. Map 인터페이스는 구조상의 차이로 인해 별도로 정의된다.
콜렉션 기본구조

Comment and share

추상클래스

제어자 중에서 abstract라는 것이 있다. 이 제어자가 클래스 앞에 붙으면 추상클래스가 된다.

클래스를 설계도에 비유한다면 추상클래스는 미완성 설계도에 비유할 수 있다. 단어 뜻 그대로 완성되지 못한 채로 남겨진 설계도를 말한다. 미완성 메소드를 포함하고 있다는 의미이다. 추상메소드를 포함하고 있다는 것을 제외하고는 일반 클래스와 전혀 다르지 않다.

추상클래스는 그 자체로 클래스 역할을 다 하지 못하지만, 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상클래스로서의 중요한 역할을 한다.

추상메서드

메소드는 선언부와 구현부로 구성되어 있다.
추상메소드란 서언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것이 추상메소드이다. 실제 내용은 상속받는 클래스에서 구현하도록 비워둔 것이다. 추상메소드 역시 키워드 ‘abstract’를 앞에 붙혀주고, 구현부가 위치할 {}대신 마침을 의미하는 ;을 작성한다.

추상클래스 사용이유

자손 클래스에서 추상메소드를 반드시 구현하도록 강요하기 위해서 이다. 상속받은 자손클래스에서는 메소드들이 완전히 구현된 것으로 인식하고 오버라이딩을 하지 않을 수 있기 때문이다.

Comment and share

Boxing과 UnBoxing

기본 타입의 값을 포장 객체로 만드는 과정을 박싱이라고 하고 반대로 포장객체에서 기본 타입의 값을 얻어내는 과정을 언박싱이라고 한다.

public class Wrapper_Ex {
    public static void main(String[] args)  {
        Integer num = new Integer(17); // 박싱
        int n = num.intValue(); //언박싱
        System.out.println(n);
    }
}

자동박싱과 자동언박싱

기본 타입 값을 직접 방싱, 언박싱하지 않아도 자동적을 박싱과 언박싱이 일어나는 경우가 있다. 자동박싱의 포장클래스 타입에 기본값이 대입될 경우에 발생한다.예를 들어 int타입의 값을 Integer클래스 변수에 대입하면 자동 박싱이 일어나 힙 영역에 Integer객체가 생성된다.

public class Wrapper_Ex {
    public static void main(String[] args)  {
        Integer num = 17; // 자동 박싱
        int n = num; //자동 언박싱
        System.out.println(n);
    }
}

Comment and share

Wrapper Class

자바의 자료형은 기본타입(primitive type)과 참조타입(reference type)으로 나누어진다. 기본타입은 char, int, float, double, boolean 등이 있고, 참조타입은 class, interface등이 있는데 프로그래밍을 하다 보면 기본 타입의 데이터를 객체로 표현해야하는 경우가 있다.
이럴 때 기본자료타입을 객체로 다루기 위해서 사용하는 클래스들을 래퍼클래스라고 한다.
자바의 모든 기본타입은 값을 갖는 객체를 생성할 수 있다. 이런 객체를 포장객체라고도 하는데, 그 이유는 기본타입의 값을 내부에 두고 포장하기 때문이다. 래퍼 클래스로 감싸고 있는 기본타입 값은 외부에서 변경할 수 없다. 만약 값을 변경하고 싶다면 새로운 포장 객체를 만들어야 한다.

래퍼클래스의 종류

기본타입 래퍼클래스
byte Byte
char Character
int Integer
float Float
double Double
boolean Boolean
long Long
short Short
래퍼 클래스는 java.lang 패키지에 포함되어 있는데, 다음과 같이 기본 타입에 대응되는 래퍼 클래스들이 있다. char타입과 int타입이 각각 Character와 Integer의 래퍼 클래스를 가지고 있고 나머지는 기본 타입의 첫 글자를 대문자로 바꾼 이름을 가지고 있다.

래퍼클래스
모든 래퍼클래스의 부모는 Object이고, 내부적으로 숫자를 다루는 래퍼클래스의 부모 클래스는 Number클래스이다. 모든 래퍼클래스는 최종 클래스로 정의된다.

Comment and share

업캐스팅

서브클래스는 슈퍼클래스의 모든 특성을 상속받는다. 따라서 서브 클래스는 슈퍼클래스가 될 수 있다.
즉, 서브 클래스가 슈퍼 클래스가 되는 것을 업 캐스팅이라고 한다.

class Person{
    String name;
    String id;

    public Person(String name){
        this.name = name;
    }
}

class Student extends Person{
    String grade;
    String department;

    public Student(String name){
        super(name);
    }
}

public class UpcastingEx{
    public static void main(String[] args){
        Person p;
        Student s = new Student("이재문");
        p = s; //업 캐스팅 발생

        System.out.println(p.name); //정상 컴파일
        Ststem.out.println(p.grade); //컴파일 오류
    }
}

Student로 인스턴스를 생성하고 Person 레퍼런스 타입으로 담았다.
다시 말해서 Person클래스의 멤버만 접근이 가능하고 Student의 멤버는 접근이 불가능하다.

다운캐스팅

서브 클래스가 슈퍼 클래스로 변했을 때 서브 클래스의 인스턴스는 잠시 가려져 있을 뿐 사라지지 않는다.
서브 클래스의 원래 특성으로 돌려 놓는게 다운 캐스팅이다.
다운 캐스팅은 업 캐스팅과 달리 명시적으로 타입을 지정해야 한다.
UpcastingEx클래스 부분만 수정한다.

public class DowncastingEx{
    public static void main(String[] args){
        Person p = new Student("이재문"); //업 캐스팅 발생
        Student s;

        s = (Student)p; //다운 캐스팅

        System.out.println(s.name); //정상 작동
        s.grade = "A"; //컴파일 오류
    }
}

Comment and share

getter, setter

private 변수를 외부에서 접근하게 하려면 public메소드를 제공한다.
값을 얻는 get()메소드를 getter, 값을 지정하는 set()메소드를 setter라고 한다.
외부 클래스에서 private멤버 변수에 직접 접근할 수 없지만,
public 메소드인 setter를 활용하여 값을 대입할 수 있다.

Comment and share

Hyeon Soo Ahn

author.bio


author.job