[Java] 배열과 ArrayList - 객체 배열

나영원·2020년 8월 27일
0

Java_basic

목록 보기
35/60

기본 자료형 배열과 참조 자료형 배열(객체 배열)

int[] arr = new int[10];

Book[] library = new Book[5];

  • 객체 배열은 자료 값을 담는 기본 자료형 배열과는 다르게 객체를 담는 배열이다. 여기서 객체는 생성자를 통해 만드는 인스턴스를 뜻한다. 위의 식은Book이란 클래스의 생성된 인스턴스를 담는 역할을 하는 객체 배열 library를 뜻한다.
  • 또한 기본 자료형이 직접 값을 메모리에 담는것과는 다르게 객체배열은 직접 인스턴스를 메모리에 기억하는 것이 아닌 주소값을 담는다. 객체 배열을 사용해 인스턴스를 담는다고해도 인스터는 여전히 힙메모리에 저장이되고 그 메모리의 주소만이 각 객체배열의 null값을 채우는 것이다.(null은 비었있다는 뜻이다)

예제

public class Book {
	
	private String title;
	private String author;
	
	public Book () {}

	public Book (String title, String author) {
		
		this.title = title;
		this.author = author;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}
	
	public void showInfo() {
		System.out.println(title+","+author);
	}
 

예제를 위해 Book 인스턴스를 만들고 변수, 생성자, get/set메서드, showInfo 메서드를 작성한다

public class BookArrayTest {

	public static void main(String[] args) {
		//1번
		Book[] library = new Book[5]; //책이 5권생긴게 아니다, address만가지고있다.
		//3번
		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","조정래"); 
		//2번
		for(int i=0; i<library.length; i++) {
			System.out.println(library[i]);
			library[i].showInfo();
		}
		/*결과값
		array.Book@5305068a
		태백산맥1,조정래
		array.Book@1f32e575
		태백산맥2,조정래
		array.Book@279f2327
		태백산맥3,조정래
		array.Book@2ff4acd0
		태백산맥4,조정래
		array.Book@54bedef2
		태백산맥5,조정래 */
		
	}
 
  • 1번 : BookArrayTest 클래스를 만들고 객체배열 library를 생성한다.(여기서 new는 배열생성의 new이지 인스턴스 생성자가 아니다)

  • 2번 : for문을 통해 객체배열을 출력하면 배열에 담겨있는 인스턴스의 주소값이 출력되는데 아직 배열을 입력하기 전이라 null값이 5개 출력된다.

  • 3번 : 객체 배열 library를 채우기 위해 생성자를 통해 Book의 인스턴스를 5개 선택한다. 그 후 2번의 출력문을 다시 출력하면 각 인스턴스의 주소값과 showInfo메서드를 통해 title과 author가 출력된다.

ArrayCopy

기본 자료형의 ArryCopy

public static void main(String[] args) {
		//1번
		int[] arry1 = {10,20,30,40,50};
		int[] arry2 = {1, 2, 3, 4, 5};
		//2번
		System.arraycopy(arry1, 0, arry2, 1, 3);
		//3번
		for(int i=0; i<arry2.length; i++) {
			System.out.println(arry2[i]);
		}
		/*결과물
		1
		10
		20
		30
		5 
		*/
	}
  • 1번 : 배열을 복사해주는 ArrayCopy를 실습 해 보기 위해 2개의 int배열을 만듭니다.
  • 2번 : System.arraycopy를 사용하면 (src, srcPos, dest, destPos, length)라고 뜨는데 앞에서부터 (복사할 배열, 복사를 시작할 위치, 붙여넣기할 배열, 붙여넣기할 위치, 복사하는 길이)를 뜻합니다. 2번에선 arry1의 0부터 3개를 복사해 arry2에 1번 부터 붙여넣기하라고 입력했습니다.
  • 3번 : for문을 통해 배열 arry2를 출력하면 결과물같이 1~3번에 내용이 복사되었으면 알 수 있습니다.

객체 배열의 ArryCopy

public static void main(String[] args) {
		//1번
		Book[] library = new Book[5]; 
		Book[] copyLibrary = new Book[5];
		//2번
		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","조정래"); 
		//3번
		System.arraycopy(library, 0, copyLibrary, 0, 5);
		//4번
		for(Book book : copyLibrary) {
			book.showInfo();
		}
        
      //결과물
      태백산맥1,조정래
	태백산맥2,조정래
	태백산맥3,조정래
	태백산맥4,조정래
	태백산맥5,조정래		
	}
  • 1번 : BookArrayTest에서 library 와 2번에 생성된 클래스들을 복사하고 library내용을 복사할 copyLibrary 배열을 생성합니다.
  • 3번 : 기본자료형 배열과 동일한 방법으로 arrycopy를 사용해서 library에 내용을 copyLibrary로 복사합니다.
  • 4번 : for(자료형, 변수명: 배열) 하면 배열을 처음부터 끝까지 돌면서 해당 변수에 값을 하나씩 대입한다는 뜻이 됩니다. 그래서 showinfo()메서드를 사용해서 객체 배열에 내용을 출력하면 결과물 같이 모두 복사된것을 확인할 수 있습니다.

ArrayCopy : 얕은복사

		//1번
		library[0].setTitle("나목");
		library[1].setTitle("박완서");
		//2번
		for(Book book : library) {
			book.showInfo();		}
		System.out.println("=============");
		for(Book book : copyLibrary) {
			book.showInfo();		}
            
           //결과물
           	박완서,조정래
			태백산맥2,조정래
			태백산맥3,조정래
			태백산맥4,조정래
			태백산맥5,조정래
			=============
			박완서,조정래
			태백산맥2,조정래
			태백산맥3,조정래
			태백산맥4,조정래
			태백산맥5,조정래
  • 1번 : ArrayCopy에 특성을 알아보기 위해 setTitle과 setAuthor 메서들 사용해 libarary[0]에 값을 바꿔줍니다.
  • 2번 : 비교를 위해 library와 copyLibrary의 내용을 출력하면 arry[0]에 내용이 둘다 바뀐 것을 알 수 있습니다. 이는 ArryCopy에서 복사는 얕은 복사로 주소값만을 복사하기 때문에 원본 내용이 바뀌면 주소값을 복사한 카피본의 내용도 바뀌는 것입니다. 참고로 내용을 직접 수정하여 복사하여 원본을 수정해도 카피본이 수정되지 않는 복사를 깊은복사 라고 합니다.

ArrayCopy : 깊은복사


		//1번
		copyLibrary[0] = new Book();
		copyLibrary[1] = new Book();
		copyLibrary[2] = new Book();
		copyLibrary[3] = new Book();
		copyLibrary[4] = new Book();
		//2번
		for ( int i= 0; i<library.length; i++) {
			copyLibrary[i].setAuthor(library[i].getAuthor());
			copyLibrary[i].setTitle(library[i].getTitle());
		}
		//3번		
		library[0].setTitle("나목");
		library[0].setTitle("박완서");
				
		for(Book book : library) {
			book.showInfo();		}
		System.out.println("=============");
		for(Book book : copyLibrary) {
			book.showInfo();		}

1번 : 직접 값을 대입하기 위해 copyLibrary에 인스턴스를 생성합니다.
2번 : for문을 통해 copyLibarary에 author에 library의 Author를 대입하고 Title도 대입합니다.
3번 : 얕은 예제와 같이 library[0]에 내용을 바꾸고 두 배열을 출력하면 이번엔 library만 바뀌고 카피본은 안바뀐 것을 확인할 수 있습니다. 이처럼 주소가 아닌 원보값을 카피본에 직접대입하는 복사를 깊은복사라고하고 필요에 따라 얕은복사와 깊은 복사 중 선택하여 사용할 수 있습니다.

향상된 for문

위의 예제에서 사용된 for문으로 배열의 요소의 처음부터 끝까지 모든 요소를 참조 할 때 편리한 반복문으로 구조는 다음과 같습니다.

for(변수 : 배열){

반복 실행문

}

profile
배우는 개발 일기

0개의 댓글