JAVA

[JAVA]배열(array), 깊은 복사, 얕은 복사, Arrays클래스

바켠주 2024. 3. 26. 04:16
728x90

배열

같은 타입의 데이터를 하나의 변수에 여러 개 담을 수 있는 저장 공간(자료구조)

배열 선언 방법

1. 공간을 먼저 선언한 배열

자료형 [] 변수명 = new 자료형 [배열 크기];

예) int[ ] arr = new int[4];

 

- 값을 부여하지 않고 선언 시 자료형 별 초기화 값

  • 정수 => 0
  • 실수 =>0.0
  • 문자 => ' '
  • 객체 => null

2. 저장될 값 미리 부여한 배열

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

=> 배열 최초 선언 시에만 가능(크기 변경이 불가능 하기 때문에)

배열의 특징

1. 선언 시 공간의 크기를 지정한다.

2. 크기는 늘거나 줄어들지 않는다.

3. 지정된 자료형의 값만 저장할 수 있다.

null

- 참조할 값(메모리 주소 )이 없다는 뜻

- *참조형 변수에만 사용이 가능하다.

- 변수명은 미리 지정하고 값은 나중에 넣는다.(이름만 만들고 공간을 안만듦)

예) int[] 변수명 = null;

 

* 일반 변수 : 변수에 값이 바로 들어있다.

* 참조형 변수 : 변수에 메모리 주소 값이 들어있어 주소를 참조해서 값을 가져온다. (배열, 문자열 등)

 

인덱스(index)

- 배열이 지닌 값이 존재하는 위치 정보

- 배열 값을 가져오거나 꺼내는 방법 : arr[인덱스 번호]  | arr[인덱스 번호] = 10; 

 

배열 길이 속성

arr.length

 

배열의 복사

일반 변수 복사 

- 일반 변수의 경우 데이터 값이 변수에 들어있기 때문에 복사가 간단하다.

int a = 3;

int b = a;

 

참조형 변수 복사

- 참조형 변수는 변수에 값의 메모리 주소가 들어있기 때문에 얕은 복사, 깊은 복사로 나뉜다.

 

얕은 복사

int[] a = {1, 2, 3, 4};
int[] b = a;

얕은 복사의 경우 a에는 배열 자체의 값이 아닌 메모리 주소가 저장되어 있다.

그렇기 때문에 배열 b에는 배열 값이 아닌 메모리 주소가 복사된다.

얕은 복사

메모리 위치가 ax10이라고 치면 a, b변수는 하나의 메모리 위치를 저장하고 있다는 뜻이다.

이로 인해 a, b 둘 중 하나라도 배열의 값이 변하면 두 개의 배열 모두 값이 변경된다.

 

깊은 복사

- 깊은 복사는 메모리 주소를 복사하지 않고 배열 공간을 다시 생성한다.

깊은 복사

공간이 각 각 만들어진다.

a, b 배열 둘 중 하나를 변경해도 서로의 값이 변하지 않는다.

 

방법1) for문 사용

int[] arr1 = {1, 3, 5, 7, 9};
int[] arr2 = new int[5];
        
for(int i = 0; i < arr1.length; i++) {
			arr2[i] = arr1[i];
		}

 

 방법2) arraycopy() 사용

int[] card = {1,6,9,8,2,7};
int[] newCard = new int[5];
System.arraycopy(card, 1, newCard, 0, 5);

arraycopy(복사할 배열, 복사할 배열 시작 인덱스, 복사 대상 배열, 복사 범위)

 

방법3) Arrays.copyOf() 사용

int[] card = {1,6,9,8,2,7};
int[] newCard = Arrays.copyOf(card,card.length);

 

객체 배열

- 기본 타입 데이터가 아닌 객체를 원소로 하는 객체 배열

- 객체에 대한 레퍼런스를 원소로 갖는 배열

class Book {
	private String title;
	private String author;
	
	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 class Example {
	public static void main(String[] args) {
		Book[] book = new Book[2];
		Scanner sc = new Scanner(System.in);
		for(int i = 0; i < book.length; i++) {
			System.out.println("제목 >> ");
			String title = sc.nextLine();
			System.out.println("저자 >> ");
			String author = sc.nextLine();
			book[i] = new Book(title, author);
		}
		
		for(int i = 0; i < book.length; i++) {
			System.out.println("(" + book[i].getTitle()
					+ ", " + book[i].getAuthor() + ")");
		}
	}
}

Arrays클래스

- 배열을 쉽게 관리할 수 있게 해주는 클래스

 

- 배열 출력 : Arrays.toString(arr)

 

- 오름차순 정렬 : Arrays.sort()

 

- 내림차순 정렬 Arrays.sort(arr, Comparator.reverseOrder())* 클래스 타입에 사용가능, int배열의 경우 사용 x, Integer타입에 사용 가능

 

- 배열 깊은 복사 : Arrays.copyOf(복사할 배열, 복사 범위) 

 

실습

버블 정렬로 배열 정렬하기

//배열 선언
int[] arr = new int[10];
//선언한 배열에 값 정의
for(int i = 0; i < arr.length; i++){
	arr[i] = (int)(Math.random() * 100) + 1;
}
System.out.println("정렬 전: " + Arrays.toString(arr));

//버블 정렬
int temp = 0;
for(int i = 0; i < arr.length; i++){
	for(int j = 0; j < arr.length -1 - i; j++){
    	if(arr[j] > arr[j + 1]){
        	temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
}
System.out.println("정렬 후: " + Arrays.toString(arr));

 

로또 생성기

//1-45
		int[] lottoArray = new int[45];
		//선택된 로또번호를 저장할 배열
		int[] lottoBalls = new int[6];
		//보너스 번호저장
		int bonus = 0;
		
		//배열에 1-45 값 순서대로 저장
		for(int i = 0; i < lottoArray.length; i++) {
			lottoArray[i] = i + 1;
		}
		int count = 0;
		
		while(count < 7) {
			//공 선택 위치를 랜덤함수로 꺼내기
			int index = (int)(Math.random() * 45);
			if(lottoArray[index] != 0) {
				if(count < 6) {
					lottoBalls[count++] = lottoArray[index];
				}else {
					bonus = lottoArray[index];
					count++;
				}
				lottoArray[index] = 0;
			}
		}
		System.out.println("로또 번호 : " + Arrays.toString(lottoBalls));
		System.out.println("보너스 번호: " + bonus);
		
		//사용자 입력
		Scanner sc = new Scanner(System.in);
		int[] userlotto = new int[6];
		count = 0;
		
		while(count < 6) {
			System.out.println((count + 1) + "번째 숫자 입력");
			int balls = sc.nextInt();
			
			for(int i = 0; i < userlotto.length; i++) {
				if(balls == userlotto[i]) {
					balls = 0;
					System.out.println("중복되었습니다.");
					break;
				}
			}
			if(balls != 0) {
				userlotto[count++] = balls;
			}	
		}
		sc.close();
		System.out.println("사용자 번호: " + Arrays.toString(userlotto));
		
		//번호 확인
		int matchCount = 0;
		boolean isBonus = false;
		
		for(int i = 0; i < userlotto.length; i++) {
			for(int j = 0; j < lottoBalls.length; j++) {
				if(userlotto[i] == lottoBalls[j]) {
					matchCount++;
					break;
				}
			}
		//보너스 번호 찾기
			if(!isBonus) {
				if(userlotto[i] == bonus) {
					isBonus = true;
				}
			}
		}
		
		//등수 출력
		if(matchCount == 6) {
			System.out.println("1등입니다.");
		}else if(matchCount == 5 && isBonus) {
			System.out.println("2등입니다.");
		}else if(matchCount == 5) {
			System.out.println("3등입니다.");
		}else if(matchCount == 4) {
			System.out.println("4등입니다");
		}else if(matchCount == 3) {
			System.out.println("5등입니다");
		}else {
			System.out.println("꽝입니다.");
		}