본문 바로가기
언어 공부/JAVA

[JAVA] 컬렉션(Collection) ArrayList, 제네릭(Generics)를 알아보자.

by 안다니. 2020. 9. 23.
반응형

 

기존의 배열은 이렇게 사용이 된다.

 

int[] number = new int[4] // 길이를 명시하고 타입을 명시한다.

//각 인덱스에 값을 넣어준다.
for(int i = 0; i < number.length; i++){
	number[i] = i;
}

//각 요소를 출력한다.
for(int i = 0; i < number.length; i++ {
	System.out.println(number[i]);
}

 

1. 길이를 미리 설정해줘야 한다.

2. 타입을 미리 설정해줘야 한다.

 

하지만, 데이터의 길이가 가변적이지 않고 미리 정해져 있는 경우에는 배열도 많이 사용하긴 합니다. 

그럼 자바 컬렉션인 ArrayList에 대해 알아보도록 하겠습니다.

 


먼저 자료의 길이가 가변적인 경우에는 List를 사용하는 게 좋습니다. List는 특징이 있습니다.

 

1. 순서대로 데이터가 저장이 된다. 

2. 값이 중복이 되어도 상관이 없다.

3. 가변적이다.

 

대표적으로 List에 포함되는 컬렉션은 다음과 같습니다.

ArrayList

LinkedList

Vector

Stack이 있습니다.

 

가장 먼저 사용이 되는 ArrayList를 보겠습니다.

 

 


반응형

ArrayList

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

// add() 메소드를 이용한 요소의 저장, add 말 그대로 저장이다.

arrList.add(1);
arrList.add(2);
arrList.add(3);
arrList.add(4);

// for 문과 get() 메소드 사용, get(index)는 말 그대로 index 번호의 값을 가지고 온다.
for (int i = 0; i < arrList.size(); i++) {
   System.out.print(arrList.get(i) + " ");
}


// remove() 메소드는 remove(index) 즉 index번의 데이터를 지우겠다는 뜻.
arrList.remove(1); 

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

// Collections.sort()를 사용해 ArrayList의 데이터를 정렬한다.
Collections.sort(arrList);


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


// set()은 set(index,data) 즉 index 번째의 데이터를, data의 값으로 변경을 해준다는 것.
arrList.set(0, 20);

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

// size()도 말 그대로 리스트의 크기, 길이라고 생각하시면 됩니다.
System.out.println("리스트 size : " + arrList.size());

get()은 Object로 값을 받습니다.

먼저 위에 주석으로 달아놨습니다. 또 많이 쓰이는 것 중에 하나는 Contains 입니다.

 

Contains는 ArrayList 안에 값이 있는지 없는지 확인하는 메소드 입니다. true or false로 반환하기 때문에 제어문을 사용할 때 보다 용이하다고 판단이 됩니다.

System.out.println(data.contains("1")); //true

 

 


 

 

제네릭에 대해서 알아보겠습니다.

 

  자바에서 제네릭은 클래스 내부에서 사용하는 데이터의 타입을 클래스의 인스턴스를 생성할 때 결정하는 것 입니다. 객체의 타입을 컴파일 시점에 체크하기 때문에 타입 안정성을 높이고 형 변환의 번거로움을 줄일 수 있습니다.

 

public class TestGene<T> 
{
    public T sample;

    public void showYourType()
    {
        if(sample instanceof Integer)
            System.out.println("Integer 타입이군요!!");
       	else if(sample instanceof String)
            System.out.println("String 타입이군요!!");
    }
}

 

위의 소스코드에서, T는 현제 타입이 정해져있지 않습니다. T는 그럼 언제 타입이 정해지나요 ? 라고 궁금하실텐데요, T는 인스턴스가 생성이 될 때 결정이 됩니다, 

 

public class Main{
    public static void main(String[] args)
    {
        TestGene<String> stringType = new TestGene<String>();
        TestGene<Integer> integerType = new TestGene<Integer>();

		stringType.sample = "Hello";
		integerType.sample = 1;

        stringType.showYourType();
        integerType.showYourType();
    }
}

 

위의 소스코드에서, <String>, <Integer> 부분이 타입입니다. 이렇게 타입이 지정이 됩니다.

 

객체를 생성하는 시점에 타입이 정해지기 때문에, 의도하지 않은 타입의 객체를 사전에 막을 수 있습니다. 

반응형

 

제네릭의 특징은 무엇인가?

 

객체 생성이 가능한 타입에서만 선언이 가능하다.

 

  제네릭은 기본 데이터 타입(int, long..)에 대해서는 지정이 불가능합니다. 다만 기본 타입을 객체 타입으로 사용하는 Wrapper 클래스(Integer, Boolean..)에는 제네릭 사용이 가능합니다.

 

 

제네릭 선언을 생략할 수 있다.

public class Data<T> {
    public T data;

    public Data(T data)
    {
        this.data = data;
    }
}
public class Main{
    public static void main(String[] args)
    {
        Data data = new Data("Hello World");
        Data<String> data2 = new Data("Hello World");
    }
}

 

 

data 객체를 만들 때, "Hello world" 즉 String 형으로 만들어지게 됩니다. 그러면 함수 인자의 정보가 Data<T>로 넘어가고, String 형이라는 걸 알게 되니까 제네릭의 생략이 가능합니다.

 

 

또 특정 자식 클래스나 부모 클래스를 선언해 타입 매개변수를 제한할 수 있습니다.

 

 

반응형

'언어 공부 > JAVA' 카테고리의 다른 글

[JAVA] 타입들, 변수의 종류 그리고 정리  (0) 2020.09.22

댓글