






Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
An overview of java arrays and arraylists, explaining their similarities and differences in terms of structure, access, and usage. It covers one-dimensional arrays, array creation, array access, and arraylist's dynamic size, as well as the advantages and disadvantages of each data structure.
Typology: Lecture notes
1 / 11
This page cannot be seen from the preview
Don't miss anything!
자바 배열 ArrayList Vector
배열의 특성 동질동질 구조구조 (homogeneous structure):^ 구조에 있는 모든 요소는 같은 타입이다. 예예 2.1)2.1)^ 일차원 배열에서 첫 슬롯에 배열에 저장되어 있는 요소들의 개수를 , 나머지 슬롯에 정수값을 저장한 배열 물리적으로 동질 구조이지만 논리적으로는 동질 구조가 아님 요소들간에요소들간에 순서가순서가 존재존재한다. 배열의 요소는 위치에 의해 접근된다. (index: 0 부터 시작 ) 배열의배열의 용량은용량은 컴파일컴파일 시간에시간에 정해진다정해진다. 배열의 모든 슬롯에 유효한 요소가 들어있을 필요는 없다. 배열의 용량을 변경할 수 없다. 임의임의 접근접근 제공제공 : 모든 요소를 바로 접근할 수 있다. 용량이 고정되어 있기 때문에 임의 접근이 가능하다.
z z z 용량 크기 : 10: 3
논리적으로는 첫 번째 요소와 나머지 요소는 다르다. 또 다른 예로 자바에서 Object 타입의 배열을 사용할 경우에는 이 배열에 저장할 수 있는 데이터 타입에 거의 제한이 없다. 하지 만 이런 예외적인 경우는 바람직한 경우가 아니다. 따라서 배열은 동질 구조가 되도록 보장 하는 것이 바람직하다. 둘째, 요소들 간에 순서가 존재한다. 배열은 각 요소를 접근하기 위해 정수 타입의 색인이 라는 정보를 사용하며, 자바는 다른 대부분의 프로그래밍 언어와 마찬가지로 첫 번째 색인 의 값은 0 이다. 색인 값에 의해 요소들 간에 순서가 결정된다. 셋째, 배열의 용량은 컴파일 시간에 정해진다. 앞으로 혼란을 줄이기 위해 배열의 용량 (capacity)은 배열에 생성할 때 지정한 배열에 저장할 수 있는 요소의 최대 개수를 나타내는 용어로 사용하며, 배열의 크기(size)는 현재 배열에 저장되어 있는 요소의 개수를 나타내는 용어로 사용한다. 넷째, 배열은 임의 접근을 제공한다. 색인 정보만 있으면 배열 내에서 요소의 위치와 상관 없이 바로 접근할 수 있다. 이것이 가능한 이유는 용량이 컴파일 시간에 고정되어 있으며, 각 요소의 크기가 정해져 있기 때문이다.
자바에서 배열은 참조 타입이다. 일차원 배열의 선언 예예 2.2)2.2) int[] numbers; // reference type C/C++ 처럼 int numbers[]; 와 같이 선언될 수도 있다. 다른 참조 타입과 마찬가지로 new 를 이용하여 생성되어야 한다. 예예 2.3)2.3) numbers = new int[10]; C/C++ 처럼 int numbers[10]; 과 같이 new 를 사용하지 않고 , 선언과 동시에 생성하는 것은 가능하지 않다. 선언과 생성을 동시에 할 수 있다. 예예 2.4)2.4) int[] numbers = new int[10]; new 를 이용하여 생성된 배열의 초기값은? 기본 값으로 자동으로 초기화된다.
자바에서 배열은 참조 타입으로서 new 연산자를 이용하여 생성된다. 배열을 선언할 때에는 배열임을 나타내기 위해 ‘[]’을 타입명 또는 배열명 뒤에 첨가한다. 보통 타입과 관련된 정보 를 한 곳에서 표현하기 위해 타입명 뒤에 첨가하는 형태를 많이 사용한다. 자바에서는 초기 값을 사용하지 않고 배열을 생성하면 기본 값으로 모든 요소의 값이 자동으로 초기화된다.
7/22 7 /
문자 배열은 String 타입의 객체가 아니다. 예예 2.10)2.10)
다음과 같은 문자 배열을 문자열로 변환할 수 있다. 예예 2.11)2.11)
문자 배열은 문자열처럼 출력할 수 있다. 예예 2.12)2.12)
void f1(String s){ … }void f2(){ char[] fruit = {‘a’, ‘p’, ‘p’, ‘l’, ‘e’}; String s = fruit;f1(fruit); // error// error }
char[] fruit = {‘a’, ‘p’, ‘p’, ‘l’, ‘e’}; String s1 = new String(fruit); // ok String s2 = new String(fruit, 2, 3); // ok “ple”
이 처럼 String 도 new 사용하여 생성할 수 연산자를 있지만 보통 new 를 생략한다경우에는 생략할 수. 물론 이 없다.
char[] fruit = {‘a’, ‘p’, ‘p’, ‘l’, ‘e’};System.out.println(fruit); 결과 : apple
C/C++와 마찬가지로 자바에서도 문자 배열과 문자열은 구분된다. 즉, 문자 배열은 String 타입의 인스턴스가 아니다. 하지만 문자 배열을 쉽게 문자열로 변환할 수 있으며, 문자 배 열은 문자열처럼 출력할 수도 있다. 예2.11에서 알 수 있듯이 new 연산자를 이용하여 String 객체를 생성할 수도 있다. 하지만 보통 String 객체는 new 연산자를 사용하지 않고 생성한다.
8/22 8 /
두 배열 변수가 같은 타입이면 상호 대입할 수 있다. 예예 2.13)2.13)^ int[] numbers = {1, 2, 3, 4}; int[] values = numbers; values 는 numbers 와 같은 배열을 참조하게 된다. 한 배열에 있는 모든 값을 다른 배열로 복사하고 싶으면 System.arraycopy 메소드를 이용한다. 예예 2.14)2.14) int[] numbers = {1,2,3,4,5}; int[] values = {11,12,13,14,15}; System.arraycopy(numbers,0,values,2,3);
1 2 3 4
numbers
values
1 2 3 4
numbers
5
11 12 13 14
values
15
1 2 3 4
numbers
5
11 12 1 2
values
3 System.arraycopy( 소스배열 , 소스배열의 시작위치 , 목적배열 , 목적배열의 시작위치 , 복사할 요소의 개수 )
자바에서 배열의 이름은 C/C++처럼 상수 포인터가 아니다. 따라서 같은 타입의 다른 배열 변수를 = 연산자를 이용하여 대입할 수 있다. 하지만 이런 대입은 값들이 복사되는 것이 아 니라 변수가 가리키는 배열이 달라질 뿐이다. 배열 변수가 가리키는 위치의 변화 없이 어떤 배열의 값만을 복사하고 싶으면 자바에서는 System 클래스의 arraycopy 메소드를 이용한다.
9/22 9 /
자바에서 배열은 참조 타입이므로 인자로 메소드에 전달하여 메소드 내에서 배열을 조작하면 메소드가 끝난 후에도 조작 결과가 계속 유지된다. 예예 2.15)2.15)
하지만 이 역시 call-by-value 형태로 전달되는 것이다. 예예 2.16)2.16)
void f1(int[] a){a[2] = 10; } void f2(){ int[] A = {1,2,3,4};f1(A); for(int i=0; i<4; i++) } System.out.println(A[i]);
결과 : 1,2,10,
void f1(int[] a){int[] B = {5,6,7,8}; a = B; }void f2(){ int[] A = {1,2,3,4}; f1(A);for(int i=0; i<4; i++) System.out.println(A[i]); }
결과 : 1,2,3,
call-by-value 방식만 제공하므로 배열을 인자로 전달하여 배열 이름이 가리키는 위치를 변 경할 수는 없다.
10 10/22/
public class A{private int value; public void set(int n) { value = n; } } // class Apublic int get() { return value; } public class B{ public static void f(A b){A c = new A(); b.set(10); b = c; } // fpublic static void main(String[] args){ A a = new A(); a.set(5);f(a); System.out.println(a.get()); } // class B} // main
a v value
b
c v
value
105
결과 : 10
이 슬라이드의 예에서는 call-by-value와 참조 타입의 관계를 설명하고 있다. 자바에서는 call-by-value 방식의 인자 전달 방법만 제공한다. 따라서 swap 메소드는 자바에서는 절대 구현할 수 없다. 하지만 참조 타입 개념에 때문에 결과가 마치 call-by-reference로 전달한 것과 같은 효과를 얻을 수 있다. f2() 메소드에서 a라는 객체는 a.set(5) 때문에 a의 value 멤버변수의 값이 5 가 된다. 이 객체를 f1() 메소드에 전달하면 a는 참조 타입이므로 f1에서 b는 a와 같은 객체를 가리키게 되며, b.set(10) 때문에 a의 멤버변수의 값은 10 으로 변경된 다. 하지만 call-by-value 방식이므로 b = c에 의해 b가 c를 가리키게 되더라도 a에는 영향 을 주지 않는다.
13 13/22/
예예 2.19)2.19)
final int[] numbers = new int[5] 에서 final 은 numbers 와 연관이 있는 것이지 배열 자체와 있는 것은 아니다.
void f(){ final int[] numbers = new int[5]; numbers[3] = 4; // ok } numbers = new int[3];^ // error
이 부분만 final
자바에서 final이라는 키워드는 주로 상수를 정의하기 위해 사용된다. 예를 들어, 값이 10 인 상수 정수 변수는 자바에서는 다음과 같이 선언한다. public static final int CAPACITY = 10; 배열을 선언할 때 final 키워드를 사용하면 배열 이름 자체가 final이 되어 배열의 이름이 가 리키는 위치를 변경할 수 없게 되지만 배열 이름을 이용하여 여전히 배열의 각 항의 내용은 변경할 수 있다.
14 14/22/
2 차원 배열은 행과 열로 구성된 테이블을 나타내기 위해 사용한다. 2 차원 배열의 선언 예예 2.20)2.20) double[][] alpha = new double[100][10]; 첫 번째 [100] 은 행을 두 번째 [10] 은 열을 나타낸다. 2 차원 배열의 접근 alpha[0][5] = 36.4; 행과 열의 개수 행의 개수 : alpha.length 열의 개수 : alpha[i].length
15 15/22/
일반적으로 2 차원 배열의 각 행의 용량은 같도록 만든다. 예예 2.21)2.21) int[][] a = new int[10][5]; 그러나 각 행의 용량이 다를 수도 있다. 예예 2.22)2.22) int[][] a = new int[2][]; a[0] = new int[5];a[1] = new int[3];
ArrayList는 java.util 패키지에서 제공하는 클래스로서, 배열과 유사하지만 배열과 달리 용량 이 부족하면 자동으로 증가된다. 이 클래스는 자바 1.2부터 제공된 클래스이며, 다중 쓰레드 를 지원하지 않는다.
ArrayList 는 java.util 패키지에 정의되어 있는 클래스로 배열과 유사하지만 배열과 달리 용량이용량이 고정되어고정되어 있지있지 않다않다. 즉 , 필요에 따라 용량이 변한다. ArrayList 는 size() 메소드를 이용하여 현재 저장되어 있는 요소의 개수를 얻을 수 있다. 배열은 특정 타입을 저장하도록 선언할 수 있지만 , ArrayList 는 Object 타입만 저장할 수 있다. ( 참조를 저장한다 .) 따라서 원시 타입은 wrapper 클래스를 사용해야 한다. 이론적으로 서로 다른 종류의 값을 ArrayList 의 요소로 사용 가능 ArrayList a = new ArrayList(); a.add(new Integer(10)); a.add(new Double(2.5));
int[] a = new int[10]; a[0] = 3; a[1] = 2.5; // error 바람직한 프로그래밍 스타일은 아니다.
ArrayList는 범용 자료구조로서 특정 타입만 저장할 수 있는 것이 아니고, 필요한 어떤 종류 의 데이터도 저장할 수 있다. 이를 위해 내부적으로 Object 배열을 이용한다. 상속 관계에서 자손 클래스의 객체는 조상 클래스 객체 타입에 저장할 수 있다. 그런데 자바에서 Object 클래스는 가장 최상위 조상 클래스이므로 어떤 종류의 객체도 저장할 수 있다. 하지만 int, double과 같은 원시 타입은 Object 타입에 저장할 수 없다. 따라서 이를 위해 자바는 Wrapper 클래스를 제공한다. Wrapper 클래스는 원시 타입을 객체처럼 다룰 수 있도록 해주 는 클래스이다. Object 배열의 또 다른 문제점은 배열의 동질 구조 특성을 보장하지 못하는
add/remove 메소드 사용시 주의점 add 는 최악의 경우 현재 저장되어 있는 모든 요소를 하나씩 오른쪽으로 이동해야 한다. 반대로 remove 는 최악의 경우 현재 저장되어 있는 모든 요소를 하나씩 왼쪽으로 이동해야 한다. 현재 크기가 용량과 같은 경우에는 현재보다 큰 용량의 배열을 생성한 다음에 기존 배열에서 요소들을 복사한다. get 메소드 사용시 주의점 반환타입이 Object 이므로 반환값을 원하는 타입으로 강제 변환 해주어야 한다. ArrayList 의 생성자 ArrayList() : 용량이 10 인 빈 리스트를 생성한다. ArrayList(int capacity): 주어진 인자에 해당하는 용량의 빈 리스트를 생성한다.
앞서 언급한 바와 같이 ArrayList는 중간에 빈 항이 존재할 수 없으므로 add 또는 remove 메소드는 최악의 경우 기존 요소를 모두 하나씩 왼쪽 또는 오른쪽으로 이동해야 한다. add 의 경우 맨 첫 항에 새 요소를 추가하는 경우가 최악의 경우이고, remove도 맨 첫 항에 있 는 요소를 제거하는 경우가 최악의 경우이다. 또한 get, set, remove 메소드의 반환 타입이 Object이므로 이 메소드를 통해 받은 객체는 원래의 타입으로 강제 변환한 후에 사용해야 한다.
20 20/22/
ArrayList 는 반복자 (iterator) 를 가지고 있다. 반복자란 구성요소를 차례로 방문할 때 사용하는 도구를 말한다. 반복자는 기본적으로 다음 두 연산을 제공한다. boolean hasNext(): 더 이상의 요소가 있는지 확인할 때 사용 Object next(): 다음 요소를 얻기 위해 사용 예예 2.23)2.23)^ void printVector(ArrayList list){ Iterator i = list.iterator(); while(i.hasNext()){ System.out.println(i.next()); } }
일반적으로 자료구조는 반복자(iterator)라는 메소드 또는 객체를 제공하여 준다. 반복자는 자료구조에 저장되어 있는 모든 요소를 차례로 방문할 수 있도록 해준다. 일반적으로 반복 자 객체는 hasNext(), next() 두 가지 종류의 메소드를 제공하여 준다. hasNext() 메소드는 더 이상 방문할 요소가 있는지 없는지 검사하는 메소드이며, 이 메소드가 참을 반환할 경우 에는 next() 메소드를 이용하여 다음 요소를 얻을 수 있다. Iterator는 java.util 패키지에 정의 되어 있는 인터페이스이다.
단순 배열 공간 문제가 중요하지 않는 경우 실행시간이 중요한 경우 요구되는 배열의 용량이 프로그램 실행마다 크게 변하지 않는 경우 배열의 크기가 프로그램이 실행되는 동안 변하지 않는 경우 배열에 있는 요소의 위치가 중요한 경우
ArrayList 공간 문제가 중요한 경우 실행시간이 중요하지 않는 경우 요구되는 배열의 용량이 프로그램 실행마다 크게 변하는 경우 배열의 크기가 프로그램이 실행되는 동안 극단적으로 변하는 경우 배열에 있는 요소의 위치가 중요하지 않는 경우 삭제 / 삽입이 대부분 끝에 이루어지는 경우
ArrayList는 일반 단순 배열에 비해 용량에 제한이 없다는 장점이 있지만 현재 용량이 꽉 차 용량을 늘려야 할 경우에는 많은 비용이 든다. 따라서 항상 배열 대신에 ArrayList를 사용하 는 것은 바람직하지 않다. 즉, 공간 문제가 중요하지 않으면 충분한 공간을 단순 배열로 확 보하여 사용하는 것이 효율면에서 ArrayList보다 좋다. 또한 프로그램이 실행될 때마다 요구 되는 배열의 용량이 변하지 않으면 ArrayList를 사용할 필요가 없으며, 마찬가지로 프로그램 이 실행되는 동안에 배열에 저장되어 있는 요소의 개수가 극단적으로 변하지 않으면 단순 배열을 사용하는 것이 바람직하다.
java.util 패키지에 포함되어 있으며 , ArrayList 와 그 기능이 매우 유사하다. 가장 중요한 차이점은 Vector 는 다중쓰레드를 지원하고 ArrayList 는 지원하지 않는다. 따라서 다중쓰레드 환경이 아니면 Vector 대신에 ArrayList 를 사용하는 것이 바람직하다. ArrayList 와 달리 capacity() 메소드를 이용하여 현재 용량을 얻을 수 있다. Vector 에 더 이상 요소를 삽입할 공간이 없으면 지정해 놓은 용량만큼 또는 기본 증가 용량만큼 자동으로 증가한다. 기본 증가 용량은 현재 용량의 두 배이다. Vector() Vector(int capacity) 증가하는 용량을 지정하고 싶으면 벡터를 생성할 때 해야 한다. Vector(int capacity, int increment)
Vector 클래스는 java.util 패키지에서 제공하는 ArrayList와 유사한 클래스로서, 이 클래스는 자바의 초기 버전부터 제공된 클래스이다. 이 클래스는 또한 ArrayList와 달리 다중쓰레드를 지원한다. 뿐만 아니라 Vector는 현재 용량이 꽉 찼을 때 증가하는 정책을 사용자가 지정할 수 있다.