Dipa's document :: Dipa's document

오늘은 컬렉션의 List 컬렉션 에 대해서 알아보도록 하겠습니다.

먼저 Collection이란?

많은 응용프로그램을 개발을 하다보면, 수많은 데이터를 처리(추가, 삭제 검색..등등) 하게 됩니다.

하지만 이러한 처리에 대해서 어떻게 하면 가장 효율적으로 할수 있을까? 라는 생각으로 접근을 할 수 있습니다. 데이터를 가장 간단하게 처리하는 방법이 무엇이 있을까여? 바로 "배열" 입니다. 데이터를 담을 공간을 어느정도 담을지 선언을 하고, 처리를한다. 무척 간단하죠? ㅋㅋㅋ

근데 배열은 많은 문제점이 있습니다. 일단 데이터를 얼마나 처리를 할지에 대한 불문명함과 또한 그런거를 모르고 아주 크게 데이터 공간을 선언을하면, 불필요한 공간이 남게 됩니다. 그리고 어떠한 인덱스 자리에 데이터를 삭제를 하게되면..그 공간은 비어있게 되는 것이지요.. 이러한 많은 문제점등이 있기 떄문에.. JAVA에서는 배열의 문제점을 해결하고 자료구조(Data Structure)를 바탕으로 컬렉션 프레임워크(Collection FrameWork)를 만들었습니다.

그렇다면,, JAVA 컬렉션에는 어떠한 것들이 있는지 살펴보도록 하겠습니다.

 * JAVA Collection FrameWork 주요 인터페이스 및 클레스

LinkedList, Stack, Vector, ArrayList 는 List인터페이스를 구현한 클레스들이고, HashSet, TreeSet은 Set인터페이스를, 그리고 HashTable, HashMap, TreeMap, Property 는 Map 인터페이스를 구현한 클레스 입니다.


 * JAVA Collection FrameWork 주요 인터페이스의 특징

 인터페이스

구현클레스 

특징 

List 

ArrayList

Vector

LinkedList 

- 순서를 유지하고 저장

-중복 저장 가능 

Set 

HashSet

TreeSet 

- 순서를 유지하지 않고 저장

- 중복 저장 불가능 

Map 

HashMap

HashTable

TreeMap

Property 

- 키와 값의 쌍으로 저장

- 키는 중복 저장 안 됨 





Posted by SH후니
,

오늘은 wrapper(포장)클레스에 대해서 살펴보도록 하자.

Wrapper클레스란 기본타임(byte,char,short,int,long,float,double,boolean)을 객체로 생성하는 클레스를 말한다. 그리고 이러한 wrapper클레스는 불변객체로써 값을 변경할 수가 없다.

예를 들어, 즉 포장이란 무엇인가? 어떠한 내용물을 담는 상자? 라고 생각하면 쉬울 것이다.

그럼 안의 내용물을 변경하려면 그 포장지를 뜯어야하지 않는가? 포장을 한다는 거 자체가 선물의 의미인데..이것을 바꾸려고 하는것은..(약간..억지의 감이 있지만)

따라서 값을 변경을 하지못하고, 값을 변경하고 싶으면 포장 객체를 생성을 하여야 한다.

 기본타입

포장 클레스

byte

Byte

char

Character

short

Short

int

Integer

long 

Long

float

Float

double

Double

boolean

Boolean

기본 타입 -> 포장 객체 : Boxint(박싱)

포장객체 -> 기본 타입 : Unboxing(언박싱)

package wrapper;

public class BoxingUnboxing {

	public static void main(String[] args) {
		Integer obj1 = new Integer(100);
		Integer obj2 = new Integer("100");
		Integer obj3 = Integer.valueOf(100);
		
		int value1 = obj1.intValue();
		int value2 = obj2.intValue();
		int value3 = obj3.intValue();
		
		System.out.println(value1);
		System.out.println(value2);
		System.out.println(value3);

//결과값 //100 //100 //100 } }

* 자동 박싱, 언박싱

박싱에도 자동 형변환처럼 자동적으로 변환을 하는 기능이 있다. 이 기능은 자바5부터 추가된 기능이다.

package wrapper;

public class AutoBoxingAutoUnboxing {

	public static void main(String[] args) {
		Integer obj1 = 100; //자동 박싱

int value = obj1; //자동 언박싱 System.out.println(obj1.intValue());

System.out.println(value);

//결과값 //100 //100 } }

마지막으로 ==,!=의 연산자이다. Wrapper클레스는 객체이기 떄문에 결국 ==,!=연산자는 포장객체의 내부의 값을 비교를 하는것이 아닌 객체의 참조를 비교를 하는것이다. 내부의 값을 비교를 하기위해서는 언박싱을 하여 비교를 하여야 하는데, 예외 적으로 내부의 값을 비교를 하는 짓도 한다..^^

타입 

값의 범위 

boolean 

true,false 

char 

\u0000 ~ \u0071 

 byte,short,int

-128~127 

왜 이런 현상이 나오는 것일까? 바로 위에 3가지의 기본 타입의 포장클레스의 캐쉬 떄문이다.

각각의 캐쉬를 소스코드로 확인을 해보자.

 private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
private static class CharacterCache {
        private CharacterCache(){}

        static final Character cache[] = new Character[127 + 1];

        static {
            for (int i = 0; i < cache.length; i++)
                cache[i] = new Character((char)i);
        }
    }


Posted by SH후니
,

오늘은 String클레스에 대해서 다뤄볼까 한다.

전에 Object클레스의 equals()를 설명을 하면서 String클레스에 대해서 다시 한번 언급을 하려고 했던 부분이 있다. 바로 객체를 선언을 할떄의 차이다.

public class internMethod {

	public static void main(String[] args) {
		String input01 = "홍길동";
		String input02 = new String("홍길동");
		
		System.out.println(input01.equals(input02));
	}
}

이것의 결과는 당연히 true가 나온다. 객체안에 있는 데이터를 비교를 하기 때문이다.

하지만.. 이렇게 되면 어떻게 될까?

public class internMethod {

	public static void main(String[] args) {
		String input01 = new String("홍길동");
		String input02 = new String("홍길동");
		
		System.out.println(input01.equals(input02));
	}
}

당연히 객체의 번지 주소를 비교를 하기 떄문에 false가 나오게 된다.

이러한 이유는 과연 무엇일까?? 

첫번쨰 소스코드의 차이의 이유는 바로 JVM에서 String 객체를 생성을 하였을 경우, 어떤 메모리 영역에 저장이 되는지에 대한 이유이다.

new 생성자를 이용해서 인스턴스를 만들고, heap 메모리에서 관리한다는 사실은 공통적이지만, String 객체는 불변객체로 한번 생성이 되면 값은 변하지가 않는다. 이런식으로 다른객체지만 객체 안의 데이터가 같은것을 무한히 생성을 하다보면 결국 메모리 관리 측명에서 비효율적이라는 판단을 한다.

이래서 만들어진 메모리 영역이 String Constant Pool이다.

또한 문자열을 변경하는 작업을 많이 할경우에는 StringBuffer와 StringBuilder클레스를 사용하면된다.

이 두 클레스는 내부 버퍼에 문자열을 저장해 두고 그안에서 추가, 수정 삭제 작업을 할 수 있도록 설계 되어 있다. 두가지를 사용하는 방법은 동일하나.. 하나의 차이가 있다면,

StringBuffer는 멀티 스레드 환경에서 사용할 수 있도록 동기화가 적용되어 있어 스레드에 안전하고,

StringBuilder는 단일 스레드 환경에서만 사용하도록 설계 되어 있다.


Posted by SH후니
,