본문 바로가기

Java

Java 자료구조 - 배열과 리스트

난 기초가 부족한 사람이야........................ 설명 못하면 너무 부족하지.. 다들 기초 빵빵하게 챙기세요!!!!!!!!!

 

배열(Array)과 리스트(List)는 상당히 비슷하지만 다르다. 

 

배열부터 알아보자.

 

배열 Array

  • Java에서 배열은 동일한 타입의 여러 값을 저장할 수 있는 연속적인 메모리 공간이다. 
  • 고정된 크기를 가진다.
  • 인덱스를 통해 요소에 접근할 수 있다.

배열 선언&초기화

// 배열 참조 변수만 선언
int[] arr1;
int arr2[];

// 선언 + 크기 할당
int[] arr3 = new int[3];

// 선언 + 초기화
int[] arr4 = {1,2,3};
int[] arr5 = new int[]{1,2,3};

// 선언된 배열의 참조 변수에 초기화 할당
arr1 = new int[3] // 0으로 채워진 배열 생성

 

배열 선언 문법이다. int형은 4byte이니까 arr 배열은 총 12byte의 메모리 크기를 차지하게 된다. 배열명 arr에는 첫 번째 인덱스 주소값이 들어가게 되는데 어? 12byte의 메모리 크기를 차지한다면서요?

 

맞다. int i와 같은 기본 자료형과 달리 배열같은 객체 자료형들은 변수에 객체의 메모리 주소만 가지고 있고 데이터들은 다른 곳에 객체가 만들어지게 된다. 메모리 영역은 따로 정리하겠다.

 

참고로 배열의 길이보다 적은 수의 요소로 초기화 하면 나머지는 타입에 맞게 자동으로 초기화되지만 길이를 초과하면 예외가 발생한다. 

 

배열 출력

System.out.println(arr); // 배열의 주소 출력

for(int i = 0; i < arr.length; i++){
   System.out.println(arr[i]);
}

System.out.println(Arrays.toString(arr)); // 메서드 이용

 

아까 말했듯이 배열명은 주소값이기 때문에 배열명으로 배열을 출력하면 주소가 나오게 되는데, 배열에 들어있는 데이터들을 출력하고 싶다면 반복문을 이용하거나 Arrays.toString() 메서드를 이용하면 된다. 

 

다만 Arrays.toString() 메소드는 import java.util이 필요하다. 뭐냐면 배열 요소를 문자열로 변환 해준다.

 

배열 크기 변경

 

사실 배열은 크기 변경이 불가하다. 고정된 크기를 가지기 때문에. 하지만 배열의 크기가 변경된 것처럼 보이게 할 수는 있다.

int[] arr = {1,2,3};

// Arrays 클래스의 copyOf 메서드 
Arrays.copyOf(arr,5); // [1,2,3,0,0]

// System 클래스의 arraycopy() 메서드
public void setSizeArray(int [] arr, int size){
   int[] newArr = new int[size];
   int length = size > arr.length ? arr.length : size;
   System.arraycopy(arr, 0, newArr, 0, length); 
}

 

arraycopy() 함수는 좀 알아보자.

public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

 

매개변수가 5개나 된다.  copyOf를 많이 쓴다고 한다.

 

Object src - 복사하고자 하는 원본 배열

 

int srcPos - 원본 배열에서 데이터를 읽을 시작 위치

 

Object dest - 새로운 배열 (복사될 배열)

 

int destPos - 새로운 배열의 시작 위치 (2로 설정하면 2번 인덱스부터 복사된다.)

 

int length - 원본 배열에서 복사되는 개수 (원본 배열의 길이보다 큰 값이 전달되는 경우 예외 발생)

 

리스트 List

 

사실 리스트랑 배열이랑 비슷하쥬?  다릅니다.

 

  • 동적 크기로 자동으로 크기가 조절된다.
  • 식별자가 없다.(인덱스 x)
  • 빈틈없는 데이터 적재 -> 삭제한 원소 뒤로 연속적 위치
  • 순차성을 보장하지 못한다 
List<Integer> intList = new ArrayList<>();
List<String> strList = new ArrayList<>();

 

주의할 점 List는 객체 타입만 저장할 수 있기 때문에 래퍼 클래스를 이용해서야 한다. (Integer, Boolean 등등)

 

혹시 여기서 나만 궁금한가..... 왜 new List가 아니고 new ArrayList인지..? 

 

결론부터 말하자면 new List는 불가하다. 왜냐하면! List는 인터페이스이기 때문이다. 인터페이스는 그 자체로 인스턴스화할 수 없다. 인터페이스를 구현한 클래스의 인스턴스를 구현해야 한다. ArrayList가 List를 구현한 클래스이다!

 

그럼 혹시.. 또 궁금하지 않나... 왜 인터페이스로 만들었을까? 인터페이스야 그렇듯 코드의 유연성 때문이다.

List<String> strList = new ArrayList<>();

strList = new LinkedList<>();

 

예를 들어 ArrayList를 LinkedList로 변경해도 쉽게 교체할 수 있다.

 

ArrayList

  • 동적 배열로 작동한다.
  • List와 다르게 인덱스 접근이 가능하다. (읽기 능력이 좋다.)
  • 특정 위치의 요소 추가, 삭제가 가능하지만 다른 데이터를 복사해서 이동해야 한다.
  • Generic을 사용하지 않고 선언한다면 다양한 타입의 객체를 저장할 수 있다. (new ArrayList();)
  • List를 구현한 AbstractList를 상속한다.
// Array -> ArrayList
String[] arr = new int[]{"1","2","3"}
List<String> list = new ArrayList<>(Arrays.asList(arr));

// ArrayList -> Array
List<String> list = new ArrayList<String>();
list.add("1");
String[] arr = new int[list.size()];
list.toArray(arr);

List<Integer> list2 = new ArrayList<>();
list2.add(1)
int[] arr2 = new int[list.size()];
for(int i = 0; i < list.size(); i++)[
	arr2[i] = list.get(i).intValue();
}

 

LinkedList

  • 노드간 연결을 통한 이중 연결 리스트이다.
  • 인덱스를 통한 접근 시 순차적 접근을 해야 한다. (읽기 능력이 떨어짐)
  • 각 요소마다 포인터가 존재해 메모리 사용량이 높다. 
  • 각 요소마다 포인터가 존재해 요소 추가, 삭제가 용이하다. 
  • List를 구현한 AbstractSequentialList를 상속한다.

List 생성 및 초기화

// 빈 ArrayList
ArrayList<String> list = new ArrayList<>();

// 사이즈 지정
ArrayList<Integer> list = new ArrayList<>(10);

// 초기화
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1,2,3));

 

List 관련 함수

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

list.add(1); // list 요소 추가

list.get(0); // list 요소 가져오기 (1)

list.size(); // list 길이 (1)

list.contains(2); // list 요소 포함 (false)

int result = list.remove(0); // list 0번째 요소 삭제 (1)
boolean result = list.remove(0); // true
list.remove(Integer.valuOf(1)); // 값이 1인 첫 번째 요소 삭제

 

자료구조 할 때 알고리즘이랑 여러가지 많이 배웠었는데 기억 하나도 안 나네.. 알고리즘도 정리해야겠다. ㅜㅜ 다들 미리 공부하세요 ㅜ


 

참고 출처

[Java]배열의 크기를 변경하는 방법 (tistory.com)

 

[Java]배열의 크기를 변경하는 방법

배열의 크기를 변경하는 방법 Java에서 배열은 고정 크기의 데이터입니다. 배열은 선언과 동시에 고정된 크기를 가지므로 배열의 크기를 직접적으로 변경하는 것은 불가능하며, Java에서도 배열

developer-talk.tistory.com