Chap 07. 배열과 ArrayList [Do it! 자바 프로그래밍 입문]

doriskim·2022년 12월 5일
0

*본 내용은 [Do it! 자바 프로그래밍 입문] 책과 강의를 보고 공부하면서 요점 정리한 내용입니다.

◼ 배열

✔ 배열 선언하기

배열은 개수를 미리 선언해야 하는 Fixed length 자료구조이다.

//자료형[] 배열이름 = new 자료형[개수];
int[] arr = new int[10];

//자료형 배열이름[] = new 자료형[개수];
int arr[] = new int[10];
  • 메모리 구조

    배열은 논리적, 물리적으로도 연속되어 있는 자료구조이다.

✔ 배열 초기화

배열은 선언과 동시에 초기화 할 수 있음
배열을 초기화 할 때는 배열의 개수를 명시하지 않음
아무런 초기화 값이 없이 선언만 한 경우, 정수는 0, 실수는 0.0, 객체 배열은 null로 초기화 됨

//int형 요소가 3개인 배열 생성
int[] studentIDs = new int[] {101, 102, 103}; // 더 많이 사용
int[] studentIDs = {102, 102, 103}; 

System.out.println(studentIDs.length); // 3출력

int[] studentIDs = new int[3] {101, 102, 103}; // 오류 발생

※주의) 오류 발생 상황

int[] numbers;
//numbers = new int[3]; (new를 해주지 않으면,)
numbers[0] = 1; // 오류 발생
int[] numbers;
numbers = {1, 2, 3}; // 오류 발생

✔ 배열의 길이(length)와 유효한 요소 값(size)

자료가 있는 요소만 출력 하려면 크기에 대한 저장을 따로 해야 한다.
임의로 size라는 변수를 이용해보자.

package array;

public class ArrayTest {

	public static void main(String[] args) {
		
		double[] num = new double[5];
		int size = 0;
		
		num[0] = 10.0; size++;
		num[1] = 20.0; size++;
		num[2] = 30.0; size++;
		
		double total = 1;
		
		for(int i = 0; i < size; i++) {
			System.out.println(num[i]);
			total *= num[i];
		}
		
		System.out.println("total = " + total);
	}

}

✔ 객체 배열 만들기

참조 자료형을 선언하는 객체 배열
배열만 생성한 경우 요소는 null로 초기화 됨
각 요소를 new를 활용하여 생성하여 저장해야 함

책이 5권이 아니라 책 가리키는 주소 5개 만들어 지는 것임.
나중에 new를 통해 book을 직접 생성하고 요소를 직접 하나하나 넣어줘야 함

Book.java

package array;

public class Book {
	private String bookName;
	private String author;
	
	public Book() {}
	public Book(String bookName, String author) {
		this.bookName = bookName;
		this.author = author;
	}
	
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	
	public void showBookInfo() {
		System.out.println(bookName + "," + author);
	}
	
}

BookArray.java

package array;

public class BookArray {

	public static void main(String[] args) {

		Book[] library = new Book[5];
		
		for(int i = 0; i< library.length; i++) {
			System.out.println(library[i]);
		}
        // null 출력됨
		
		library[0] = new Book("태백산맥1", "조정래");
		library[1] = new Book("태백산맥2", "조정래");
		library[2] = new Book("태백산맥3", "조정래");
		library[3] = new Book("태백산맥4", "조정래");
		library[4] = new Book("태백산맥5", "조정래");
        
		for(int i = 0; i < library.length; i++) {
			System.out.println(library[i]);
		}
		// 주소값 출력됨

		
		for(int i = 0; i < library.length; i++) {
			library[i].showBookInfo();
		}
        //책 정보 출력됨
	}

}

실행 결과

null
null
null
null
null
array.Book@1d81eb93
array.Book@7291c18f
array.Book@34a245ab
array.Book@7cc355be
array.Book@6e8cf4c6
태백산맥1,조정래
태백산맥2,조정래
태백산맥3,조정래
태백산맥4,조정래
태백산맥5,조정래

✔ 배열 복사하기

기존 배열과 같은 배열을 만들거나 배열이 꽉 찬 경우 더 큰 배열을 만들고 기존 배열 자료를 복사할 수 있다.
복사 과정에서 사이즈 넘어가면 오류가 발생한다.

System.arraycopy(src, srcPos, dest, dextPos, length);
  • src: 복사할 배열 이름
  • srcPos: 복사할 배열의 첫 번째 위치
  • dest: 복사해서 붙여 넣을 대상 배열 이름
  • destPos: 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치
  • length: src에서 dest로 자료를 복사할 요소 개수

ArrayCopy.java

package array;

public class ArrayCopy {

	public static void main(String[] args) {
		
		int[] array1 = {10, 20, 30, 40, 50};
		int[] array2 = {1, 2, 3, 4, 5};
		
		System.arraycopy(array1, 0, array2, 1, 4);
		for(int i = 0; i < array2.length; i++) {
			System.out.println(array2[i]);
		}

	}

}

실행 결과

1
10
20
30
40

✔ 객체 배열 복사하기

  • 얕은 복사
    배열 요소의 주소만 복사되므로 배열 요소가 변경되면 복사된 배열의 값도 변경된다.
    복사된 배열은 같은 인스턴스를 가리킨다.

ObjectCopy.java

package array;

public class ObjectCopy {

	public static void main(String[] args) {
		
		Book[] bookArray1 = new Book[3];
		Book[] bookArray2 = new Book[3];
		
		bookArray1[0] = new Book("태백산맥1", "조정래");
		bookArray1[1] = new Book("태백산맥2", "조정래");
		bookArray1[2] = new Book("태백산맥3", "조정래");
		
		System.arraycopy(bookArray1, 0, bookArray2, 0, 3);
		
		for(int i = 0; i< bookArray2.length; i++) {
			bookArray2[i].showBookInfo();
		}
		
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		
		for(int i = 0; i < bookArray1.length; i++) {
			bookArray1[i].showBookInfo();
		}
		
		System.out.println("---------------");
		
		for(int i = 0; i < bookArray2.length; i++) {
			bookArray2[i].showBookInfo();
		}

	}

}

실행 결과

태백산맥1,조정래
태백산맥2,조정래
태백산맥3,조정래
나목,박완서
태백산맥2,조정래
태백산맥3,조정래
---------------
나목,박완서
태백산맥2,조정래
태백산맥3,조정래

-깊은 복사
서로 다른 인스턴스의 메모리를 요소로 가지게 된다.
객체배열을 선언만 한다고 인스턴스가 생성되지 않으므로 new를 통해 새로운 인스턴스를 생성한다.

ObjectCopy.java

package array;

public class ObjectCopy {

	public static void main(String[] args) {
		
		Book[] bookArray1 = new Book[3];
		Book[] bookArray2 = new Book[3];
		
		bookArray1[0] = new Book("태백산맥1", "조정래");
		bookArray1[1] = new Book("태백산맥2", "조정래");
		bookArray1[2] = new Book("태백산맥3", "조정래");
		
		//새로운 인스턴스 생성
		bookArray2[0] = new Book();
		bookArray2[1] = new Book();
		bookArray2[2] = new Book();
		
		// arraycopy는 사용하지 않는다.
		// System.arraycopy(bookArray1, 0, bookArray2, 0, 3); 
		
		//복사 과정
		for(int i = 0; i< bookArray1.length; i++) {
			bookArray2[i].setAuthor(bookArray1[i].getAuthor());
			bookArray2[i].setBookName(bookArray1[i].getBookName());
		}
		
		bookArray1[0].setBookName("나목");
		bookArray1[0].setAuthor("박완서");
		
		for(int i = 0; i < bookArray1.length; i++) {
			bookArray1[i].showBookInfo();
		}
		
		System.out.println("---------------");
		
		for(int i = 0; i < bookArray2.length; i++) {
			bookArray2[i].showBookInfo();
		}

	}

}

실행 결과

나목,박완서
태백산맥2,조정래
태백산맥3,조정래
---------------
태백산맥1,조정래
태백산맥2,조정래
태백산맥3,조정래

◼ 향상된 for문 (enhanced for loop)

배열 요소의 처음부터 끝까지 모든 요소를 참조할 때 편리한 반복문

for(변수 : 배열){
	반복 실행문;
}
  • String 예시
    1번과 2번은 같다.
		String[] strArr = {"Java", "Android", "C"};
		
		// 1번
		for(int i = 0; i < strArr.length; i++) {
			System.out.println(strArr[i]);
		}
		
		// 2번
		for(String s : strArr) {
			System.out.println(s);
		}

실행 결과

Java
Android
C
Java
Android
C
  • int 예시
		int[] arr = {1, 2, 3, 4, 5};
		for(int num : arr) {
			System.out.println(num);
		}

실행 결과

1
2
3
4
5

◼ 다차원 배열

2차원 이상의 배열
지도, 게임 등 평면이나 공간을 구현할 때 많이 사용됨

이차원 배열의 선언과 구조

자료형[][] 배열이름 = new 자료형[행개수][열개수];
int[][] arr = new int[2][3];

선언과 초기화

int[][] arr = {{1, 2, 3}, {4, 5, 6)};

TwoDimensionArray

package array;

public class TwoDimensionArray {
	
	public static void main(String[] args) {
		
//		int[][] arr = new int[2][3];
		int[][] arr = {{1,2,3},{4,5,6}};
		
		System.out.println(arr.length); // 2 출력
		System.out.println(arr[0].length); // 3 출력
		System.out.println(arr[1].length); // 3 출력
		
		for(int i = 0; i < arr.length; i++) {
			for(int j = 0; j< arr[i].length; j++) {
				System.out.println(arr[i][j]);
			}
		}
		// 1 2 3 4 5 6 출력됨
	}
	
}

◼ ArrayList 클래스

✔ ArrayList 클래스

기존 배열은 길이를 정하여 선언하므로 사용 중 부족한 경우 다른 배열로 복사하는 코드를 직접 구현해야 한다.
중간의 요소가 삭제되거나 삽입되는 경우도 나머지 요소에 대한 조정하는 코드를 구현해야 한다.

ArrayList 클래스는 자바에서 제공되는 객체 배열이 구현된 클래스이다.
여러 메서드와 속성 등을 사용하여 객체 배열을 편리하게 관리할 수 있다.
가장 많이 사용하는 객체 배열 클래스이다.

※ ctrl + shift + 'o': 자동으로 필요 클래스 import 해줌

✔ ArrayList 클래스 주요 메서드

메서드설명
boolean add(E e)요소 하나를 배열에 추가합니다. E는 요소의 자료형을 의미합니다.
int size()배열에 추가된 요소 전체 개수를 반환합니다.
E get(int index)배열의 index 위치에 있는 요소 값을 반환합니다.
E remove(int index)배열의 index 위치에 있는 요소 값을 제거하고 그 값을 반환합니다.
boolean isEmpty()배열이 비어 있는지 확인합니다.

※ 이클립스에서 F1을 눌러 JavaDoc을 활용해 ArrayList에 대해 더 알아볼 수 있다.

✔ ArrayList 클래스 사용하기

ArrayList<E> 배열 이름 = new ArrayList<E>();

사용할 객체를 E 위치에 넣고 ArrayList 메서드를 활용하여 추가하거나 참조할 수 있다.

ArrayListTest.java

package array;

import java.util.ArrayList;

public class ArrayListTest {

	public static void main(String[] args) {
		
		ArrayList<String> list = new ArrayList<String>();
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		
		// 1.
		for(String s : list) {
			System.out.println(s);
		}
		
		// 2. 1.의 함수 사용한 버전
		for(int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
			//System.out.println(list[i]); // 오류 발생(ArrayList는 인덱스 연산자 제공하지 않음)
		}
	}
}

✔ 배열 응용 프로그램

학생의 성적 총점 계산 프로그램
Student.java

package arraylist;

import java.util.ArrayList;

public class Student {

	private int studentID;
	private String studentName;
	private ArrayList<Subject> subjectList; // ArrayList 활용
	
	public Student(int studentID, String studentName) {
		this.studentID = studentID;
		this.studentName = studentName;
		
		subjectList = new ArrayList<Subject>();
	}
	
	public void addSubject(String name, int score) {
		Subject subject = new Subject();
		subject.setName(name);
		subject.setScorePoint(score);
		
		subjectList.add(subject);
	}
	
	public void showStudentInfo() {
		int total = 0;
		for(Subject subject : subjectList) {
			total += subject.getScorePoint();
			System.out.println("학생 " + studentName + "님의 " + subject.getName() + 
					" 과목의 성적은 " + subject.getScorePoint() + "점 입니다.");
		}
		System.out.println("학생 " + studentName + "님의 총점은 " + total + "점 입니다.");
	}
}

Subject.java

package arraylist;

public class Subject {

	private String name;
	private int scorePoint;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getScorePoint() {
		return scorePoint;
	}
	public void setScorePoint(int scorePoint) {
		this.scorePoint = scorePoint;
	}

}

StudentTest.java

package arraylist;

public class StudentTest {

	public static void main(String[] args) {

		Student studentLee = new Student(1001, "Lee");
		studentLee.addSubject("국어", 100);
		studentLee.addSubject("수학", 90);
		
		studentLee.showStudentInfo();
		
		System.out.println("---------------");
		
		Student studentKim = new Student(1002, "Lee");
		studentKim.addSubject("국어", 100);
		studentKim.addSubject("수학", 90);
		studentKim.addSubject("영어", 80);
		
		studentKim.showStudentInfo();
	}

}

실행 결과

학생 Lee님의 국어 과목의 성적은 100점 입니다.
학생 Lee님의 수학 과목의 성적은 90점 입니다.
학생 Lee님의 총점은 190점 입니다.
---------------
학생 Lee님의 국어 과목의 성적은 100점 입니다.
학생 Lee님의 수학 과목의 성적은 90점 입니다.
학생 Lee님의 영어 과목의 성적은 80점 입니다.
학생 Lee님의 총점은 270점 입니다.

0개의 댓글