Java finalize

JAVA 2015. 10. 26. 01:42


'JAVA' 카테고리의 다른 글

Commons DBCP  (0) 2015.11.07
자바 classpath  (0) 2015.11.03
Call By Value vs Call By Reference  (0) 2015.09.14
List, Map, Set - Collection  (0) 2015.08.29
자바 8 특징  (0) 2015.08.29
Posted by slender ankles
,

자바의 call by value와 call by reference에 대해서 설명해보겠다.

흔히 C와 C++에서는 주소값을 저장하는 포인터 변수와 레퍼런스 변수를 사용하는데 자바에서는 이러한 개념이 없지 않은가?


결론은

원형 타입(primitive)타입일 때는 call by value가, 객체 타입(Object)타입일 때는 call by reference가 사용된다. 


객체가 넘어가면 Call By Reference로 동작한다고 했다.

그렇다면 다음은 어떻게 동작하겠는가??

public class Test4 {
 
    int a;
    public Test4(int a){
        this.a = a;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test4 t = new Test4(1);
        int i = 5;
        changeInt(i);
        System.out.println(i); // (1)       
        changeTest(t);
        System.out.println(t.a);    // (2)
        changeTestInt(t);
        System.out.println(t.a); // (3)
    }
    public static void changeInt(int a){
        a = 10;
    }
    public static void changeTest(Test4 t){
        t = new Test4(100);
    }
    public static void changeTestInt(Test4 t){
        t.a = 10;
    }
}
 
cs


(1) 5

=> int 형은 primitive 타입이기 때문에 call by value다. 그래서 함수를 지나면 지역변수가 사라지게 된다.

(2) 1

=> 메서드 안에서 new로 객체가 할당되었다. 그리고 외부 변수에 대입해주었다. 

그렇다면 new로 생성한 값 100으로 연결되어 되지 않은가? 하지만 아니다. new로 할당된 객체도 지역이 종료되면 없어진다.

(3) 10

외부에서 주입된 t에 대해서 값을 변경시켜주는 메서드를 실행했다. 값이 바뀐다. 


아무래도 난해했던 것은 (2)이 아닐까 싶다. 










'JAVA' 카테고리의 다른 글

자바 classpath  (0) 2015.11.03
Java finalize  (0) 2015.10.26
List, Map, Set - Collection  (0) 2015.08.29
자바 8 특징  (0) 2015.08.29
volatile 키워드 vs synchronized 키워드  (0) 2015.08.29
Posted by slender ankles
,

List, Map, Set - Collection

JAVA 2015. 8. 29. 16:00

리스트, 맵, 셋은 콜렉션 클래스를 상속받은 클래스들이다.

 

List 

- 수집 순서가 있음

- 동일한 데이터에 대한 중복 입력이 가능

- 순차적인 대량의 데이터를 액세스하거나 입력할 때 유리한 방식

List분류
 
ArrayList
 
- capacity는 수용할 수 있는 데이터의 개수를 의미
 
- 데이터가 늘어나게 되면 capacity가 동적으로 확장됨.

- 크기를 지정하지 않으면 capacity는 기본 10이다.
- 데이터를 10개 이상 사용한다면 무조건 10보다는 크게 잡아놔야 된다. 그래야
동적으로 capacity가 늘어나면서 수행되는 오버헤드를 줄일 수 있다.
- 데이터의 삽입, 삭제가 좋지 않다.(배열들을 뒤로 밀거나 당겨야 하므로)
 
Vector
- ArrayList와 거의 동일. 다만 StringBuilder와 StringBuffer의 
차이처럼 동기화를 지원하느냐 하지 않느냐의 차이
 
LinkedList
- capacity의 개념이 없다.
 
- 데이터를 삽입할 때는 주소값만 연결하면 되므로 고정된 크기의 연속된 집합인 
ArrayList에 비해 삽입 삭제가 용이
 
- 검색 할 때는 처음부터 순차적으로 접근해야 하므로 속도가 느리다.
 
 

cs


Map

Key & Value 형태의 자료구조

- 수집의 순서를 기억하지 않음

- 동일한 키값을 중복하여 입력 할 수 없음


Set

- 중복데이터의 입력을 불허

- 순서가 없다.

- 중복되지 않은 수(데이터)를 구할 때 용이하다.

- 집합의 개념

'JAVA' 카테고리의 다른 글

Java finalize  (0) 2015.10.26
Call By Value vs Call By Reference  (0) 2015.09.14
자바 8 특징  (0) 2015.08.29
volatile 키워드 vs synchronized 키워드  (0) 2015.08.29
인스턴스 메소드 vs 클래스(스태틱) 메소드  (0) 2015.08.25
Posted by slender ankles
,

자바 8 특징

JAVA 2015. 8. 29. 15:58

자바 8의 특징은 무엇인가?

1) 람다식의 출현

람다식을 간략히 정리하면 변수에 로직을 대입하는 것을 말한다.


2) foreach 메소드의 등장

foreach는 자바스크립트에서 보았듯이 객체를 전달하여 index를 지정하여 iteration하는 것이 아니라 array나 list등을 전달하여 자동적으로 순회하게끔 하는 것이다. 



[참고]JIT컴파일러란 무엇인가?

Just In Time 컴파일러라는 뜻으로 인터프리터의 장점과 컴파일러의 장점을 모두 활용하여 사용하는 것입니다. 일부는 컴파일된 기계어를 만들고, 일부는 바이트 코드를 해석하는 것을 통해 번역속도와 실행속도의 장점을 취하는 방법입니다.

[참고] 컴파일러 vs 인터프리터

컴파일러는 번역속도가 느린 대신에 실행 속도가 빠르고 (전체를 기계어로 번역해놓기 때문에 실행속도가 빠름)

인터프리터는 번역속도가 빠른 대신에 실행 속도가 느리다.(번역한 코드를 한줄한줄 해석하여 실행하기 때문)


람다식

람다식은 무엇인가? 

변수에 로직을 대입할 수 있는 문법을 말한다. 기존의 익명함수의 사용을 보완하여 더 간결하고 가독성 좋은 코드를 만들 수 있다. 

람다식을 이해해보자.

참조 : http://jinson.tistory.com/208

위의 참조에서 좋은 글귀를 보고 나름대로 이해하고 해석해서 다시 재작성해본다. 

람다식이 필요한 이유를 다음과 같이 설명해주고 있다. 

우선 리스트와 리스트의 모든 원소를 이터레이션하는 코드를 작성해보자.

1
2
3
4
5
List<Integer> numbers = Arrays.asList(123456); 
 
for (int number : numbers) {
    System.out.println(number);
}
cs

우리는 이러한 리스트를 순회할 때 간단히 for문을 통해서 로직을 수행하는데 여기에 숨겨진 깊은 뜻이 있다고 한다. 

딸과 함께 거실에 떨어져있는 장난감을 주울려고 한다. 

나: "소피아, 장난감 정리하자. 땅에 어떤 장난감이 있지?"

소피아: "어. 공이 있네"

나: "그래. 공을 박스에 넣자. 땅에 또 뭐가 있지?"

소피아: "어. 인형이 있지"

나: "그래. 인형을 박스에 넣자. 땅에 또 뭐가 있지?"

소피아: "어. 책이 있네"

나: "그래. 책을 박스에 넣자. 땅에 또 뭐가 있지?"

소피아: "아니. 아무것도 없어"

나: "잘했네. 이제 다 했다"

사실 바닥에 있는 장난감을 주워라고 한 마디로도 이해하고 실행할 수 있는 것이 사람이지만 실제로 다음과 같은 과정이 가지고 오는 이점 또한 있다. 소피아는 양손에 장난감을 들어 박스에 넣을 수도 있고, 박스로부터 가벼운 것부터 나를 수도 있을 것이라는 것이다. 즉 내부 이터레이션을 수행 할 수 있다는 것이다. 즉 JIT컴파일러가 내부적으로 병렬화하여 원소 처리를 최적화해서 처리할 수도 있다는 말이다. 


다음의 예를 보자.

자바 8 이전에는 내부이터레이션을 사용하기 위해서는 이름 없는 내부클래스를 만들어야 했다. 

1
2
3
4
5
numbers.forEach(new Consumer<Integer>() {
    public void accept(Integer value) {
        System.out.println(value);
    }
});
cs

반복문을 순회하면서 새로이 만들어진 consumer객체의 accept를 정의하여 호출하고 있다.

위의 코드를 자바 8에서의 람다식을 이용해서는 다음과 같이 처리할 수 있다. 


1
numbers.forEach((Integer value) -> System.out.println(value));
cs


화살표의 왼쪽은 매개 변수 목록이고, 오른쪽은 몸체이다. 컴파일러는 내부적으로 람다식을 분석하여 Consumer클래스의 미구현된 메소드(즉, accept 메소드)와 동일한 타입인지 검사하여 람다식을 마치 consumer인터페이스를 구현한 클래스인 것처럼 활용한다. 

내부적으로 accept인지를 분석한다고 했으므로 컴파일러는 분석능력이 있는 것이다. 다음과 같이 인자를 생략해도 가능하다고 한다. 

1
numbers.forEach(value -> System.out.println(value));    // 식(1)
cs

이 문장 역시도 더 줄일 수 있다. 자바 8에서 새로이 등장할 메소드 참조(method reference)를 활용하면

더 간단하게 만들 수도 있다. 자바 8에서 도입될 :: 구문을 활용하여 다음과 같이 정적 메소드나 인스턴스 메소드를 참조할 수 있다. 

1
numbers.forEach(System.out::println);  // 식(2)

cs


람다식은 왜 필요한가?

간단히 말하면 익명함수를 사용할 것이라면, 복잡하지 않게 간결함을 제공해주겠다는 것이 그 필요 이유라고 할 수 있다.


Map의 HashCollision 처리 변화

Java 8에서도 역시 해시맵의 충돌을 Seperate Chaining 방식을 통해 해결한다. 하지만 이전과 다르게 해시충돌이 일어난 리스트의 개수가 8개 이상이 되면 링크드 리스트가 아닌 트리로 바꾼다. 그리고 6개까지 줄어들면 다시 링크드 리스트로 바꾼다.

왜 하나의 수를 경계로 삼지 않고 해시충돌의 수를 8개, 6개로 하는가 하면 데이터의 수가 하나를 경계로 왔다갔다할 때는 리스트에서 트리로 바꾸거나 트리에서 리스트로 바꾸는 오버헤드가 증가하기 때문에 이렇게 로직을 구성한다.








Posted by slender ankles
,

volatile과 synchronized 키워드. 무엇을 하는 녀석들인가?


volatile과 synchronized 키워드 멀티스레드 환경에서 읽고, 쓰기에 대해서 원자성을 보장해주는 동기화 도구입니다. 


그렇다면 두 키워드의 차이는 무엇인가?


차이점을 간략히 한 줄로 설명하자면, volatile은 변수에 한해서만 동기화를 해주는 도구이며, synchronized는 작업에 대해서 동기화를 지원해주는 도구입니다.

한줄만으로는 이해하기 힘들것이므로 가볍게 예를 하나 들어보겠습니다. 

long stat = 324L;

위와 같은 변수 선언에서의 stat에 대한 volatile키워드는 stat에 대해서 서로 다른 스레드로부터 읽고 쓰기에 대한 원자성을 보장해줍니다. 스레드 A, 스레드 B가 읽고 쓰면서 같은 변수에 대해서 다른 값을 읽어가는 것을 방지해주죠.

int value = stat + 10;

위와 같은 경우가 조금 다릅니다. 

내부적으로 JVM은 value 변수를 읽어오고, stat 변수를 읽어오며, 10을 더하는 동작이 분리되어 있습니다. 이 같은 경우 어떤 스레드가 stat에 10이 더해진 변수 value를 읽어 갈 수도 있고, 그렇지 않을 수도 있다는 것입니다. 


하지만 synchronized키워드는 작업 자체에 대해 원자성을 보장해주는 도구이므로 이 같은 문제를 해결 할 수 있습니다. 

이 것이 synchronized와 volatile키워드의 차이인 것입니다. 


'JAVA' 카테고리의 다른 글

List, Map, Set - Collection  (0) 2015.08.29
자바 8 특징  (0) 2015.08.29
인스턴스 메소드 vs 클래스(스태틱) 메소드  (0) 2015.08.25
자바 Null Pointer Exception막는 방법  (0) 2015.08.18
자바 제네릭(Generic)이란?  (0) 2015.08.06
Posted by slender ankles
,


'JAVA' 카테고리의 다른 글

자바 8 특징  (0) 2015.08.29
volatile 키워드 vs synchronized 키워드  (0) 2015.08.29
자바 Null Pointer Exception막는 방법  (0) 2015.08.18
자바 제네릭(Generic)이란?  (0) 2015.08.06
자바 리플랙션(Reflection) API  (0) 2015.08.05
Posted by slender ankles
,

자바 Null Pointer Exception막는 방법

참조 : http://www.jpstory.net/2014/02/avoid-nullpointerexception/


NPE, Null Pointer Exception 이란?

Null값 때문에 발생하는 Runtime Exception입니다. 

null인 객체에 접근하여 발생하는 예외도 있지만, 그 값이 모호한 경우에 다양한 버그를 만들어냅니다.

예를 들어, 메소드의 호출결과로 null이 반환되었다면 데이터가 없는 것인지, 아니면 메소드의 로직이 실패한 것인지를 정확히 판단하기 힘듭니다. 

어떤 특정한 상황에서 개발자가 일부러 null값을 집어넣을 수도 있기 때문에 null값이 반드시 에러다. 라고는 말할 수 없습니다.

어쨌든 이러한 애매모호한 런타임에러는 디버깅하기 힘들기 때문에, 코드를 작성 할 때 신중히 작성할 필요가 있습니다.

매번 느끼지만 고민을 많이하는 개발자만큼 능력있는 개발자는 없는 것 같습니다. 시간에 쫓기거나 하면서 코딩하는 것이 

얼마나 좋지 않은 것인지에 대해서 매번 깨닫습니다.


Null Pointer Exception을 예방하는 코딩습관에 대해서 설명합니다. 

1) Equals 메소드 사용시

문자열 비교시 non-null String 기준으로 비교합니다. 

equals 메소드는 symmetric하므로 a.equals(b)와 b.equals(a)가 동일합니다. 

절대 널이 발생하지 않는 문자열이 있다면 이를 주 객체로 지정해주는 것이 좋습니다. 


2) toString()보다는 valueOf()를 사용할 것

3) 메소드에서 return null을 사용하지 않기


4) null을 파라미터로 넘기지 말 것


5) 불필요한 autoboxing, unautoboxing 피하기 & Object보다는 기본형 사용하기

6) chaining 메소드 호출 자제하기


Library를 통해서 null pointer exception을 처리해주는 방법

이 사실 더 좋은 방법이라고 생각합니다. 

Apache Commons lang, Google Guava(예전 Google Collections) 등 null safe한 method를 이용하는 방법입니다.

1) Apache Commons의 StringUtils

String의 null 체크를 간단히 할 때 많이 사용하는 클래스입니다. StringUtils.isNotEmpty(), isBlank(), isNumeric(), isWhiteSpace() 등이 있죠.



2) Guava의 Optional 클래스 이용하기

Optional는 nullable한 T를 non-null 값으로 대체시키기 위한 방법인데요. (말이 어렵죠?)
Optional 객체는 non-null인 T reference를 포함하거나 아무것도 포함하고 있지 않습니다.

한마디로 Optional 객체는 명시적으로 null 값을 갖지 않는다는거죠.
NullObject Pattern을 일반화시켰다고나 할까요? 바로 이 점을 이용해서 NPE를 예방합니다.

– absent : 아무 것도 포함하고 있지 않은 상태
– present : non-null 값을 갖은 상태

1) Optional 객체의 생성 (static 메소드)

Optional.of(T)
– T로 받은 non-null 값을 포함하는 Optional 객체 반환, T가 null 일 경우 NPE 발생
Optional.absent()
– 아무것도 포함하고 있지 않는 absent Optional 객체 반환
Optional.fromNullable(T)
– T로 받은 값이 non-null일 경우 present로, null일 경우 absent로 처리한 Optional 객체 반환

2) Optional 객체를 다루기 위한 메소드

boolean isPresent()
– Optional 객체가 non-null 인스턴스를 포함할 경우 true 반환
T get()
– Optional 객체가 present 일 경우 포함하고 있는 인스턴스를 반환, absent일 경우 IllegalStateException 발생
T or(T)
– Optional 객체의 present 값을 반환. 만일 값이 없을 경우 명시한 T를 반환 (기본값)
T orNull()
– Optional 객체의 present 값을 반환, 만일 값이 없을 경우 null을 반환. fromNullable의 역임
Set asSet()
– Optional 객체에서 포함하고 있는 인스턴스의 변경 불가능한 싱글톤 Set을 반환. 만일 인스턴스가 없다면 변경불가능한 Empty set을 반환

3) Guava의 Preconditions 또는 NullPointerTester 클래스 이용하기


Nullness Anotation 활용하기

메소드의 return값 또는 파라미터의 null 허용여부를 Annotation을 이용하여 지정합니다. 코딩 습관 들이기 3, 4번 항목을 제약하기 위해 사용하는데요.

IDE에서 지원하는 @Nullable, @NotNull 등의 Annotation을 사용하면 코드에서 NPE 발생 가능여부를 미리 경고해줍니다. 또 해당 Annotation 제약사항을 위반했을 경우 컴파일시 NPE가 아닌 IllegalArgumentException 또는 IllegalStateException이 발생됩니다. Argument로 NotNull이어야 한다고 정했는데 Null이 들어왔다면 의미상 NPE보다는 잘못된 Argument가 맞겠죠?

현재 ItelliJ, Eclipse IDE 및 Find Bugs에서는 서로 다른 Annotation 라이브러리를 사용하는데요. JCP에 Software Defect Detection하기 위한 Annotation이 JSR-305로 요청 중이나 현재 dormant(중단) 상태네요. 언제 JDK에 포함될런지는 모르겠네요 :'(

Posted by slender ankles
,

우선, 자바 제네릭(Generic)이 왜 필요한지에 대해 현실세계에 빚대어 보겠습니다.

우리가 소위 핸드폰을 판다고 해보자. iPhone6일 수도 잇고, iPhone6+일수도 있고 갤럭시 s6, edge, note4, G4일수도 있습니다.

핸드폰을 파는 사람은 여러가지 모델이 아니라 하나의 모델만 판다면 구분할 필요없이 한가지 색깔, 한가지 가격을 정해놓고 판매할수가 있게 된다. 제네릭은 여러 가지 모델을 취급하게 설계 할 수 있다. 그래서 형변환과 타입체크를 할 필요가 없게되는 것이다. 



이 것을 자바세계로 끌고오면, 

<String> 제네릭은 String만, <Interger>제네릭은 Integer클래스만 사용할 수 있습니다. 

<iPhone>제네릭에는 iPhone객체만 취급할 수 있고, <GalaxyS6>제네릭은 GalaxyS6만 취급  할 수 있다는 말입니다. 

그렇지 않으면 에러가 납니다. 


제네릭은 왜 사용할까?

여러 개의 타입을 취급할 때에 형변환이 이루어지는데, 형변환은 컴파일 타임에는 에러가 나지 않는다. 제네릭을 사용하게 되면 당연히 클래스를 여러개 만들고 형변환을 할 필요가 없다는 장점과 타입체크를 할 필요가 없다는 장점이 있고 잘못된 타입이 들어가게 되면 컴파일 타임에 오류를 확인 할 수 있다.  


와일드 카드

?는 알 수 없는 타입을 뜻한다.

<?> - 모든 객체 자료형, 내부적으로 Object로 인식한다.

<? super 객체자료형> - 명시된 객체 자료형과 그 상위 객체, 내부적으로 Object로 인식한다.

<? extends 객체자료형> - 명시도니 객체 자료형과 이를 상속한 하위객체, 내부적으로는 명시한 객체 자료형을 인식한다. 


'JAVA' 카테고리의 다른 글

인스턴스 메소드 vs 클래스(스태틱) 메소드  (0) 2015.08.25
자바 Null Pointer Exception막는 방법  (0) 2015.08.18
자바 리플랙션(Reflection) API  (0) 2015.08.05
자바 해시맵(HashMap)  (0) 2015.08.05
자바 문자열  (0) 2015.07.26
Posted by slender ankles
,

리플랙션(Reflection)

"어떤 것에 대한 설명 또는 묘사" "거울 등에 미친 모습"

자바에서는 클래스 메서드의 내부 구조 를 들여다 볼 때 사용하는 도구라는 뜻

구체적인 클래스 타입을 알지 못해도, 컴파일된 자바 바이트 코드를 이용하여 역으로 클래스에 대한 정보를 알아내어, 클래스를 사용할 수 있는 기법을 말한다. 마치 거울에 비친 모습과 비슷하다고 하여 리플랙션이라는 이름이 붙여진 것


Class.newInstance()                   주어진 클래스의 인스턴스를 생성

Class.getName()                       클래스의 이름을 반환

Class.getMethod()                     클래스의 선언된 모든 public 메서드의 목록을 반환

Method.invoke()                        해당 메서드를 호출

Method.getParameterTypes()         메서드의 매개변수 목록을 배열로 반환



리플랙션 API가 필요한 이유는 무엇일까?

코드의 재사용성 및 유지보수를 쉽게 하기 위해서 서블릿에서 클래스 파일을 분리시키는데요.

이렇게 되면, 원래의 클래스명과 타입같은 것을 알아내기가 힘들어집니다. 하지만 리플렉션 api를 이용해서 class의 이름이나 타입 등을 알아낼 수 있는데, 이렇게 되면 모델, 뷰, 컨트롤러를 분리하는 코드를 만들기가 쉬워집니다.

스프링에서는 리플렉션이 컨트롤러에 구현되어 있다고 할 수 있습니다. 


추가적으로, Junit과 같은 테스트 라이브러리에서는 reflection api를 통해서 불특정 클래스를 불러와서 실행시키거나 하는 동작에도 유용하게 사용된다고 합니다.



'JAVA' 카테고리의 다른 글

자바 Null Pointer Exception막는 방법  (0) 2015.08.18
자바 제네릭(Generic)이란?  (0) 2015.08.06
자바 해시맵(HashMap)  (0) 2015.08.05
자바 문자열  (0) 2015.07.26
자바가 확장한 객체지향  (0) 2015.06.30
Posted by slender ankles
,

자바 해시맵(HashMap)

JAVA 2015. 8. 5. 18:29

자바 해시맵(HashMap)

해시맵(HashMap)과 해시테이블(HashTable)을 정의하면 "키에 대한 해시 값을 사용하여 값을 저장하고 조회하며, 키-값 쌍의 개수에 따라 동적으로 크기가 증기하는 associative array"라고 할 수 있다. 

어떤 수들 N에 대하여 M크기만큼의 배열을 만들고 해시함수를 통해 index를 계산해서 O(1) 시간에 접근 가능하게 만든다. 다음은 간단히 해시 함수 함수를 구현한 것이다.

1
int index = X.hashcode() % M;
cs


해시 충돌(Hash Collision)

해시함수를 통해 계산된 index값에 이미 다른 자료가 저장되어 있는 경우 이를 해시 충돌이라고 한다. 


자바에서 해시 충돌을 막는 두 가지  방법

Open Addresing 방법

데이터를 삽입하려는 해시 버킷이 이미 사용 중이라면 다른 해시 버킷에 해당 데이터를 삽입하는 방식이다. 데이터를 저장, 조회할 해시 버킷을 찾을 때는 선형 검색법(linear probing), 2차 검색법(quadratic probing) 등의 방법을 사용한다. 

* Open Addressing을 해결하는 4가지 방법

(1) 선형 탐사

해시 함수로부터 얻어낸 주소에 이미 다른 데이터가 입력되어 있음을 발견하면, 현재 주소에서 고정 폭(예를 들면 1)으로 다음 주소로 이동합니다.

(2) 제곱 탐사

선형 탐사가 다음 주소를 찾기 위해 고정폭만큼 이동하는 것에 비해 제곱 탐사는 이동폭이 제곱수로 늘어나는 것이 다르다.

(3) 이중 해싱

클러스터 방지를 위해, 2개의 해시 함수를 준비해서 하나는 최초의 주소를 얻을 때 또 다른 하나는 충돌이 일어났을 때 탐사 이동폭을 얻기 위해 사용

(4) 재해싱

해시 테이블의 크기를 늘리고, 늘어난 해시 테이블의 크기에 맞추어 테이블 내의 모든 데이터를 다시 해싱하는 것


Seperate Chaining 방법

해시함수를 통해 도출된 인덱스가 서로 같은 자료들을 연결 리스트(Linked List)로 연결하는 방법이다.

자바 7까지는 해시충돌난 자료들을 연결리스트로 연결했지만, 자바 8에서는 자료의 개수가 8개 이상이 될 때는 트리 형태로 만든다. 또 6개로 줄어들면 다시 링크드 리스트로 만든다. 해시 충돌 나는 자료들의 개수가 많아지면 트리를 통해 특별한 저장공간을 사용하지만 빠른 성능으로 값을 찾아낼 수 있다. 



'JAVA' 카테고리의 다른 글

자바 제네릭(Generic)이란?  (0) 2015.08.06
자바 리플랙션(Reflection) API  (0) 2015.08.05
자바 문자열  (0) 2015.07.26
자바가 확장한 객체지향  (0) 2015.06.30
자바와 객체지향  (0) 2015.06.30
Posted by slender ankles
,