Java - 배열

kojam9041·2022년 3월 16일
0

KH정보교육원 - JAVA

목록 보기
7/12

배열

* 배열을 학습하기 이전에는, 변수를 활용하여 코드를 구성하였다.
* 변수 : 해당 자료형의 값 하나만을 담을 수 있는 공간(값 자체가 변할 수 있음)
* 배열 : 해당 자료형의 값 여러 개를 담을 수 있는 공간	
*
* [표현법]
* 1. 배열선언
*   int[] arr; 
*   => Stack영역에 주소값을 넣을 공간을 할당한다.
*
* 2. 배열 할당
* int[] arr = new int[3];
* => Heap영역(new)에 int형 값이 들어갈 공간을 3칸 만든다.
* => 각각 [0], [1], [2]의 인덱스 번호를 부여받는다.
* => 배열의 크기 = 3개 / 마지막 인덱스 = 2	
*
* 3. 배열 초기화
* arr[0] = 10;
* arr[1] = 20;
* arr[2] = 30;

package com.kh.array;

import java.util.Scanner;

public class A_Array {

	public void method1() {
    	/*
	    배열을 왜 써야 하는가?
	    예시
		0, 1, 2, 3, 4를 기록해야 함.
		
		1.변수만을 이용
		int num1=0;
		int num2=1;
		int num3=2;
		int num4=3;
		int num5=4;
		출력하기 위해서 출력문을 5번이나 작성함.
		System.out.println(num1);
		System.out.println(num2);
		System.out.println(num3);
		System.out.println(num4);
		System.out.println(num5);
		for(int i=1; i<=5; i++) {
			System.out.println(numi); 이런식으로 쓸 수는 없음.
		}
		int sum = 0;
		for(int i=1; i<=5; i++) {
			sum = sum + numi; 이런식으로 쓸 수 없음.
		}
		반복문을 사용하고자 하나, 위와같이 반복문을 쓸수가 없으니
		sum = num1+num2+num3+num4+num5; // 이런식으로 써줘야 함.
		*/
        
		2.배열을 이용
	    // 반복문을 이용해서 값을 대입
	    for(int i=0; i<5; i++) {
	    	arr[i]=i;
	    }
	    // 반복문을 이용해서 값을 출력
	    for(int i=0; i<5; i++) {
	    	System.out.println(arr[i]);
	    }

		System.out.println(arr); // [I@6d06d69c
		// arr에는 주소값이 담김 - Stack영역
		// 따라서, arr에는 값을 담을 수 없음.
		
	}

	public void method2() {
		// 변수 선언과 동시에 대입
		int i = 10;	
		
		// 배열 선언과 동시에 할당
		int[] iArr = new int[5]; 
		
		System.out.println("i : "+i);	
		// 10
		System.out.println("iArr : "+iArr); // [I@6d06d69c 
		//주소값 : Stack(주소값) -> Heap(실제값)
		System.out.println("iArr의 해시코드값 : "+iArr.hashCode()); // 1829164700
		// 해시코드 : 주소값을 10진수의 형태로 보여줌
		// 해시코드를 이용하면 Stack의 동등비교가 가능함.
		
		double[] dArr = new double[3]; 
		System.out.println("dArr : "+dArr); // [D@7852e922
		System.out.println("dArr의 해시코드값  : "+dArr.hashCode()); // 2018699554
		
		/*
		 * 기본자료형 : 실제 값을 Stack에 바로 담을 수 있는 변수
		 * boolean, char, byte, short, int long, float, double
		 * => 변수 이름을 댔을 때, 실제 들은 값을 바로 받아볼 수 있음.
		 * => 이를 '일반변수'라고 함.
		 * 
		 * 참조자료형 : 주소값을 담고 있는 변수.실제 값이 Heap영역에 있음.
		 * String, 자료형[](배열), new(Scanner, A_Array,...)
		 * => 실제 값이 아닌, 그 실제값이 존재하는 곳의 주소값을 받아볼 수 있음.
		 * => 이를 '참조변수'(reference Variable)이라고 함.
		 * String str = "바보";
		 * System.out.print("바보");
		 * => 다만, String은 예외적으로 일반변수처럼 주소값이 아닌 실제값을 바로 호출할 수 있음.
		 */
	}

	public void method3() {
		int[] iArr = new int[3]; // [0], [1], [2]
		double[] dArr = new double[3]; // [0], [1], [2]
		System.out.println(iArr); // 주소값 : [I@6d06d69c
		System.out.println("iArr[0] : "+iArr[0]); // 0
		System.out.println("iArr[1] : "+iArr[1]); // 0
		//...
		// 배열 사용시, 반복문이랑 같이쓰는 연습
		
		/*
		 * 배열을 출력할 때, 반복문을 쓰면 더 좋음.
		 * 0번 인덱스부터 마지막 인덱스까지 순차적으로 출력할 수 있음
		 * 마지막 인덱스 값 == 배열의 크기-1
		 * 
		 * 배열의 크기를 아는 방법
		 * [표현법]
		 * 배열명.length
		 * => 배열의 길이를 알려주는 변수
		 * => length()아님. 이건 메소드임.
		 */
		System.out.println("iArr의 크기 : "+iArr.length);  // 3([0], [1], [2])
		System.out.println("dArr의 크기 : "+dArr.length);  // 3([0], [1], [2])
		
		/*
		 * for문에서 반복의 횟수를 지정하는 가장 편한 방법
		 * 1. 변수에서의 반복
		 * int i=0 ; i<반복횟수 ; i++
		 * int i=0 ; i<5 ; i++ (5번 반복)
		 * 
		 * 2. 배열의 크기만큼 반복
		 * int i=0 ; i<반복횟수 ; i++
		 * int i=0 ; i<iArr.length ; i++ 
		 */
		System.out.println();
		for(int i=0; i<iArr.length; i++) {
			System.out.println(iArr[i]);
		}
		// iArr[0] == 0
		// iArr[1] == 0
		// iArr[2] == 0
		
		System.out.println();
		for(int i=0; i<dArr.length; i++) {
			System.out.println(dArr[i]);
		}
		// dArr[0] == 0.0
		// dArr[1] == 0.0
		// dArr[2] == 0.0
		
		/*
		 * 배열의 특징
	     * 값을 초기화, 대입하지 않았음에도 잘 출력되는 것을 볼 수 있음.
	     * => int형 배열의 경우는 '0', double형 배열은 '0.0'이 담김
	     * => 배열 구조상, 실제 들어있는 값은 Heap영역에 존재함.
	     * => 이 Heap영역은 특징상, 절대 빈 공간으로 존재할 수 없음.
	     * => 이에 값을 설정하지 않으면, 각 자료형의 기본값을 Heap에 대입함.
	     * 기본값 : 0(정수형), 0.0(실수형), ' '(문자형)
	     * [참고]
	     * 기본자료형 변수 : 내가 직접 초기화(값을 처음 대입)를 함.
	     * 참조자료형 변수 : JVM이 알아서 초기화를 해줌.(Heap영역을)
		 */
         
		
		int num;
		System.out.println(num);
        /*
		[오류메세지]
		The local variable num may not have been initialized
		변수에 값이 대입되지 않아 발생하는 문제임.
		*/
        
		String str;
		System.out.println(str);
        /*
		[오류메세지]
		The local variable num may not have been initialized
		변수에 값이 대입되지 않아 발생하는 문제임.
		*/
	}

	public void method4() {
		int[] arr = new int[5]; //[0],[1],[2],[3],[4]
		arr[5] = 6;
		arr[6] = 7;
		System.out.println(arr[5]);
		System.out.println(arr[6]);
        /*
		[오류메세지]
		ArrayIndexOutOfBoundsException: 5
		당연히 인덱스의 범위를 초과하여 오류메세지가 나옴.
		(인덱스는 4까지인데 5에 접근하고자 하였음.)
        */
		
//		값 대입을 위한 반복문
		for(int i=0; i<arr.length; i++) {
			arr[i]=i+1;
		}
		
//		값 출력을 위한 반복문
		for(int i=0; i<arr.length; i++) {
			System.out.println(arr[i]);
		}
		
//		값 출력과 누적 덧셈을 하기 위한 반복문
		System.out.println();
		int sum=0;
		for(int i=0; i<arr.length; i++) {
			sum = sum+arr[i];
			System.out.println(sum);
		}
	}

	public void method5() {
    	/*
		10칸짜리 배열을 만든 후
		배열 각 방에 랜덤한 수의 값을 대입
		랜덤 값의 범위는 51~100까지
		int random = (int)((Math.random()*50)+51); 총50개, 시작값:51
		for문 밖에다 작성하면, 한번만 출력된 랜덤값이 배열에 모두 채워짐.
		*/
        
		int[] arr = new int[10];
		for(int i=0; i<arr.length; i++) {
			arr[i] = (int)((Math.random()*51)+50); 
			//이렇게, 매번 랜덤값을 나오게 해줘야함.
		}
		for(int i=0; i<arr.length; i++) {
			System.out.println("arr["+i+"] : "+arr[i]);
		}
	}

	public void method6() {
		
		int[] arr = new int[5];
		System.out.println("주소값 : "+arr); // [I@6d06d69c
		System.out.println("해시코드값 : "+arr.hashCode()); // 1829164700
		
		int value = 2;
		for(int i=0; i<arr.length;i++) {
			arr[i] = value;
			value += 2;
		}
		for(int i=0; i<arr.length;i++) {
			System.out.print(arr[i]+" ");
		}
		/*
		 * 배열의 가장 큰 단점
		 * 내가 할당했던 시점에서, 한번 지정한 배열의 크기는 변경이 불가하다.
		 * => 배열의 크기를 굳이 변경하고자 한다면,
		 * => 어쩔 수 없이 새로운 배열을 다시 만들어서 써야함.
		 * => 이 경우, 선언 및 할당을 다시해야 하나?
		 */
		
		//할당만 다시 해봄
		arr = new int[7]; 
		System.out.println("새로운 주소값 : "+arr);  //[I@7852e922
		System.out.println("새로운 해시코드값 : "+arr.hashCode()); //2018699554
		
		/*
		 * 메모리 영역에는 공간을 할당할 때는 항상 고유한 주소값이 부여됨.
		 * => 기존에 생성된 주소값과 절대 중복되지 않음.
		 * => 새롭게 할당만 한 경우에는 
		 * => 기존에 참조하고 있던 기존의 주소값이 새로운 주소값으로 변경되며
		 * => 기존의 연결이 끊기고, 새로운 연결로 바뀜.
		 * => 연결이 끊어진 배열은 메모리의 Heap영역에 떠다니다가
		 * => 일정 시간이 지나면 정리가 됨.
		 * 	  (자동 메모리 관리 : Garbage Collection(Collector), GC)
		 */
        
		// 연결을 바꾸는게 아니라, 그냥 끊고 싶다면?
		arr = null;  // 아무것도 존재하지 않는 값을 의미.
		System.out.println(arr); // null이라고 뜸.
		arr[0] = 10; // 유효하지 않은 코드
        
		/*
		 * System.out.println(arr);
		 * System.out.println(arr.hashCode());
		 * [오류메세지]
		 * NullPointerException
		 * 찾아갈 주소지가 없는데, 어떻게 0번째 방에 접근해서 값을 넣어?라고 말하는것임.
		 * null이 들어있는 곳 기준으로, 어떠한 행위를 하면 발생하는 오류
		 */
		
		/*
		 * 기본자료형의 기본값
		 * 정수형 : 0
		 * 실수형 : 0.0
		 * 문자형 : ' '(공백)
		 * 참조자료형 : null => 찾아갈 주소값이 없음.
		 * 
		 */
	}

	public void method7() {
		/*
		 * 3명의 사용자에게 매번 키의 정보를 입력받아,
		 * 배열에 담아두고
		 * 3명의 키를 각각 출력, 총합계, 평균을 계산하여 출력
		 */
		Scanner sc = new Scanner(System.in);
		
		// 3명의 키 값을 담을 double형 배열 하나 만들기
		// 3명의 키를 각각 스캐너로 입력받아 각 방에 담기.
		double[] heights = new double[3];
		double sum = 0;
		double avg = 0;
		for(int i=0; i<heights.length; i++) {
			System.out.print("키 입력(cm) : ");
			heights[i] = sc.nextDouble();
			sc.nextLine();
		}
		// 3명의 키 정보 출력 + 총합계,평균 구하기
		for(int i=0; i<heights.length;i++) {
			System.out.println((i+1)+"번째 사람의 키 : "+heights[i]+"cm");
			sum = sum + heights[i];
		}
		System.out.println("키의 총합계 : "+sum+"cm");
		System.out.println("키의 평균 : "+(sum/heights.length)+"cm");
		//System.out.printf("키의 평균 : %.2f"cm",(sum/heights.length));
	}

	public void method8() {
	// 사용자에게 문자열 하나를 받고
	// 각각의 문자들을 char 배열로 옮겨담기
	Scanner sc = new Scanner(System.in);
		
	// 1. 사용자로부터 문자열을 입력
	System.out.print("문자열 입력 : ");
	String str = sc.nextLine();
		
	// 2. char배열 만들기(배열 크기는 문자열의 길이만큼)
	char[] chArr = new char[str.length()];
		
	// 3. 각각의 문자들을 char배열로 옮겨담기
	// 공백도 문자로 취급되어 출력됨.
	//		          배열의 길이로 조건식을 씀 
		for(int i=0; i<chArr.length;i++) {
			chArr[i] = str.charAt(i);
			System.out.println((i+1)+"번째 문자열 : "+chArr[i]);
		}
	}

	public void method9() {
	// 변수의 경우
	// 1. 변수 선언
	int num;
	// 2. 변수의 선언,초기화
	int num1 = 1;
    
	// 배열의 경우
	// 1. 배열의 선언,할당
	// (이 경우, 값의 대입은 JVM에 의해 기본값으로 초기화 및 대입됨.)
	int[] arr = new int[4];
	// 2. 배열의 선언,할당,초기화
	// 방법1
	int[] arr1 = new int[] {1,2,3,4};
	// 방법2
	int[] arr2 = {1,2,3,4};
		
	// 배열의 동등비교
    // Stack의 주소값(해시코드)간의 동등비교이기 때문에
	// 결과값은 모두 false가 나옴.
	System.out.println(arr == arr1);	// false
	System.out.println(arr1 == arr2);	// false
	System.out.println(arr2 == arr);	// false

	System.out.println(arr.hashCode() == arr1.hashCode());	// false
	System.out.println(arr1.hashCode() == arr2.hashCode());	// false
	System.out.println(arr2.hashCode() == arr.hashCode());	// false
	}

	public void method10() {
	// 좋아하는 과일의 개수를 입력받은 후에,
	// 이 개수만큼 배열의 방을 지정하여
	// 과일명을 입력받아서 문자열 배열에 대입
	Scanner sc = new Scanner(System.in);
	System.out.print("과일의 개수 : ");
	// 1. 과일의 개수를 입력받음
	int size = sc.nextInt();
	sc.nextLine();
		
	// 2. 과일의 개수만큼 방의 크기를 지정
	String[] fruitsName = new String[size];
		
	// 3. 좋아하는 과일명을 입력받아서 각 방에 넣기
	for(int i=0; i<fruitsName.length;i++) {
		System.out.print("좋아하는 과일명 입력 : ");
		fruitsName[i] = sc.nextLine();
	}
    
	// 4. 과일명이 제대로 들어갔는지 결과를 출력
	for(int i=0; i<fruitsName.length;i++) {
		System.out.println("입력된 과일명 : "+fruitsName[i]);
	}
}
}

배열복사

 * 배열의 자료형, 실제값, 크기를 똑같이 복사함.
 * [방법]
 * 1. 얕은 복사 : 배열의 주소값만 복사하는 개념.
 * 2. 깊은 복사 : 동일한, 새로운 배열을 생성하여 내부값들을 복사하는 개념.

얕은 복사


package com.kh.array;

import java.util.Arrays;

public class B_ArrayCopy {

	public void method1() {
//		*얕은 복사 : 주소값만을 복사함.
//		복사를 하기 전, 전제조건으로 당연히 '원본'이 존재해야 함.
//		원본 배열
//		1. 배열 선언과 동시에 초기화
		int[] origin = {1,2,3,4,5};

//		2. 원본배열 출력		
		for(int i=0; i<origin.length; i++) {
			System.out.print(origin[i]+" ");
		}
        
//		복사본 배열
//		1. 원본 복사(주소값)
		int[] copy = origin; 
		for(int i=0; i<copy.length; i++) {
			System.out.print(copy[i]+" ");
		}
//      Stack 
//		origin(0123) -----> Heap : 0123({1,2,3,4,5}) 
//		copy(0123) ----------↑
		
//		2. copy를 가지고 수정하기
		copy[2] = 100;
		for(int i=0; i<copy.length; i++) {
			System.out.print(copy[i]+" ");
		}
        
//		3. copy를 수정 한 후, origin확인
		for(int i=0; i<origin.length; i++) {
			System.out.print(origin[i]+" ");
		}
//		원본이 훼손됨. 
//		=> copy와 origin이 같은 주소값으로 연동이 되어버려
//		=> copy를 수정하여도 origin까지 수정이 되어버림
//
//      Stack
//		origin(0123) -----> Heap : 0123({1,2,100,4,5}) 
//      copy(0123) ----------↑
//		(copy[2]=100;)   

		System.out.print("\n 원본 배열의 해시코드 : "+origin.hashCode());
		System.out.print("\n 복사본 배열의 해시코드 : "+copy.hashCode());
//		둘다 같은 해시코드로, 다시말하면 둘이 같은 배열이라고 볼 수있음.
	}

깊은 복사


* 깊은 복사 : 새로운 배열을 생성하여 내부값들을 동일하게 복사함

* for문을 이용하는 방법
* 새로운 배열을 생성한 후, 각 인덱스 별로 내부 값을 일일이 대입시켜줌.
	public void method2() {
//		원본 배열 선언,할당,대입
		int[] origin = {1,2,3,4,5};
		
//		복사본 배열 선언,할당
//		{0,0,0,0,0}			{1,2,3,4,5}
		int[] copy = new int[origin.length];
//      => 새로운 배열을 선언하고 공간을 할당(new)

//		값 대입
		for(int i=0; i<copy.length; i++) {
			copy[i] = origin[i];
		}
        
//		복사본 출력
		for(int i=0; i<copy.length; i++) {
			System.out.print(copy[i]+" ");
		}
        
//		복사본 배열 수정
		copy[2] = 100;
		for(int i=0; i<copy.length; i++) {
			System.out.print(copy[i]+" ");
		}
        
//		원본 확인
		for(int i=0; i<origin.length; i++) {
			System.out.print(origin[i]+" ");
//		원본이 훼손되지 않은 것을 볼 수 있음.
//		=> 주소값을 복사하는 얕은 복사와 달리,
//		=> 깊은 복사는 배열을 따로 만들고, 같은 값을 각각 대입하는 것이기에
//		=> 주소값이 달라, copy가 origin을 훼손시키지 못함.
//		Stack : origin(0123) -----> Heap : 0123({1,2,3,4,5}) 
//		        copy(1234) -------> Heap : 1234({1,2,100,4,5})
		}
		System.out.println();
		System.out.println("\n원본 배열의 해시코드 : "+origin.hashCode());
//		1829164700
		System.out.println("복사본 배열의 해시코드 : "+copy.hashCode());
//		2018699554
//		주소값(해시코드)가 다른 것을 볼 수 있음.
	}

* 새로운 배열을 생성한 후,
* System이라는 클래스에서 arraycopy라는 메소드를 호출하여 복사
* 이 메소드는 static영역에 올라가 있어 import문을 사용하지 않음.
	public void method3() {
//		원본 배열
		int[] origin = {1,2,3,4,5};
		
//		복사본 배열
		int[] copy = new int[10];
//		     		{0,0,0,0,0,0,0,0,0,0}
		
//		arraycopy
//		origin 배열, 0번째 인덱스부터, 총 5개의 값을,
//		copy배열, 0번째 인덱스부터, 복사하여 넣겠다.
//		System.arraycopy(원본배열명, 원본배열 시작 index,
//		                 복사배열명, 복사배열이 들어갈 index, 개수)
		System.arraycopy(origin, 0, copy, 0, 5);
//					{1,2,3,4,5,0,0,0,0,0}
		System.arraycopy(origin, 0, copy, 2, 5);
//					{0 0 1 2 3 4 5 0 0 0}
		System.arraycopy(origin, 0, copy, 1, 3);
//					{0 1 2 3 0 0 0 0 0 0}
		System.arraycopy(origin, 2, copy, 9, 2);
//					{0 0 0 0 0 0 0 0 0 3} 4 
//		[오류메세지]
//		ArrayIndexOutOfBoundsException
//		인덱스의 범위를 넘어서서 값을 복사하려고 했음.
//		1. 인덱스 범위를 벗어나면 위와 같이 오류가 뜨니 주의.
//		2. 복사를 하고 남은 부분은 JVM에 의해서 초기화가 되었던 0이라는 숫자가 유지됨.
//		3. 자유자재로 내가 원하는 자리에 원하는 만큼만 부분 복사가 가능함.
//		4. import문을 쓰지 않아 static이 붙어있을 것임.

		for(int i=0; i<copy.length; i++) {
			System.out.print(copy[i]+" ");
		}
		System.out.println();
		System.out.println("원본해시코드 : "+origin.hashCode());
		System.out.println("복사본해시코드 : "+copy.hashCode());
//		다른 주소값을 가지고 있는 것을 볼 수 있음.
//		배열 수정시, 원본에 영향을 주지 않는다는 것을 유추할 수 있음.
	}

* Arrays
* 배열에 무엇인가를 처리하고자 할 때 사용하는 클래스임.
* 이 중에서도 copyOf라는 메소드를 이용하여 복사함.    
	public void method4() {
//		원본배열
		int[] origin = {1,2,3,4,5};
		
//		복사본 배열
		int[] copy = Arrays.copyOf(origin, 7);
//					       {1 2 3 4 5 0 0 }
		for(int i=0; i<copy.length; i++) {
			System.out.print(copy[i]+" ");
		}
//		유추해볼 수 있는것
//		1. 반복 몇번? 7번 => 배열의 크기 ==7
//		2. 1,2,3,4,5가 들어가고 뒤에 0,0이 붙음
//		=> 5,6번째 인덱스가 존재하며 이 공간은 JVM이 자동으로 채워줌.
//		3. import문을 쓰지 않아 static이 붙어있을 것임.
//		[표현법]
//		자료형 복사본배열명 = Arrays.copyOf(원본배열명, 복사본배열의 크기)
		System.out.println();
		System.out.println("원본해시코드 : "+origin.hashCode());
		System.out.println("복사본해시코드 : "+copy.hashCode());
//		다른 주소값을 가지고 있는 것을 볼 수 있음
//		배열 수정시, 원본에 영향을 주지 않는다는 것을 유추할 수 있음.
	}

* clone메소드를 호출하여 복사   
	public void method5() {
//		원본배열
		int[] origin= {1,2,3,4,5};

//		[표현법]
//		자료형[] 복사본배열명 = 원본배열명.clone();
		int[] copy = origin.clone();
//		인덱스지정x, 복사개수지정x => 따로 옵션이 존재하지 않음.
		
//		복사본 출력
//		for문을 이용하여 출력 => [1,2,3,4,5]
		/*
		System.out.print("[");
		for(int i=0; i<copy.length; i++) {
			if(i<copy.length-1) { // 마지막 바로 이전 값에서는 콤마를 첨가O
				System.out.print(copy[i]+", ");
			}else {// 마지막 값에서는 콤마를 첨가X
				System.out.print(copy[i]);
			}
		}
		System.out.println("]");
		*/
//		Arrays에서 제공하는 배열을 한개의 문자열로 표현하여 내보내주는 메소드
//		toString()
//		[표현법]
//		Arrays.toString(내가 출력하고자 하는 배열명);
//		=> 앞과 뒤에 [], 값들 사이에는 콤마(,)를 찍어서 각 인덱스에 담긴 값들을
//		       하나의 문자열로 연이어 만들어 주는 메소드
		System.out.println(Arrays.toString(copy));
		
//		해시코드 확인
		System.out.println();
		System.out.println("원본해시코드 : "+origin.hashCode()); // 1829164700
		System.out.println("복사본해시코드 : "+copy.hashCode()); // 2018699554
	}
}

이차원 배열

1차원 배열을 여러개 묶은 개념
* 1차원배열이 계란 한줄이면
* 2차원 배열은 계란 한판에 해당함.
*
* [표현법]
* 1. 2차원 배열의 선언
* int[][] arr;
* int[] arr[];
* int arr[][];
*
* 2. 2차원 배열의 할당
* arr = new int[2][3];
* 
* 3. 2차원 배열의 선언, 할당
* int[][] arr = new int[2][3];
*
* [구조]
* 우선적으로, 주소값이 담긴 [행크기]만큼의 배열이 만들어지고,
* 각각 담긴 주소값을 기준으로, [열크기]만큼의 배열이 연결되어서 값을 찾아감
*
* Stack : 0123 --> Heap : arr[0]{1234} ->  1234{0 0 0 0 0}
*		  arr   		  arr[1]{2345} ->  2345{0 0 0 0 0}
*		                  arr[2]{3456} ->  3456{0 0 0 0 0}
*	                      arr[i] 0123      arr[i][j] 1234,2345,3456
*
* System.out.println(arr);
* // [[I@6d06d69c]] - Stack(arr[i]의 주소값)
* System.out.println(arr[0]);  
* // [I@7852e922] - heap(arr[i][j]의 주소값)
* System.out.println(arr[0][0]);  
* // 0 - heap(arr[i][j]의 실제값)

package com.kh.array;

import java.util.Scanner;

public class C_DimensionalArray {

	public void method1() {

	    /*
		 * 해당 2차원 배열의 행크기를 아는 법
		 * => 2차원배열명.length
		 * 해당 2차원 배열의 열크기를 아는 법
		 * => 2차원배열명[해당열].length
		 */
        int[][] arr = new int[3][5];
		System.out.println("행의 길이 : "+arr.length); // 3
		// arr[]의 개수(행의 길이)를 반환함.
		System.out.println("0번째 행의 열의 길이 : "+arr[0].length); // 5
		System.out.println("1번째 행의 열의 길이 : "+arr[0].length); // 5
		System.out.println("2번째 행의 열의 길이 : "+arr[0].length); // 5
		// arr[] 하나의 열의 길이를 반환함. => arr[][]
		/*
		 * 출력
		 * arr[0][0]
		 * arr[0][1]
		 * arr[0][2]
		 * arr[0][3]
		 * arr[0][4]
		 * ============
		 * arr[1][0]
		 * arr[1][1]
		 * arr[1][2]
		 * arr[1][3]
		 * arr[1][4]
		 * ============
		 * arr[2][0]
		 * arr[2][1]
		 * arr[2][2]
		 * arr[2][3]
		 * arr[2][4]
		 * 
		 * 규칙 : 행수는 고정된 상태에서,
		 * 열수만 0에서부터 배열의 크기 전까지 1씩 증가함.
		 */
//		바깥쪽 for문 => 행수를 움직임
//		i가 3번 돌음(0,1,2) - 행의 길이만큼
		for(int i=0; i<arr.length;i++) {
//			안쪽 for문 => 열수를 움직임.
//			j가 5번 돌음(0,1,2,3,4) - 0번째 행의 열의 길이만큼
			for(int j=0; j<arr[i].length; j++) {
				System.out.print(arr[i][j]+ " ");
//				if((j+1)%5==0) {
//					System.out.print(arr[i][j]);
//					System.out.println();
//				}else {
//					System.out.print(arr[i][j]+",");
//				}
			}
			System.out.println();
		}
		
	}

	public void method2() {
//		2차원 배열(행크기 : 3, 열크기 : 5)
		int[][] arr = new int[3][5];
		
//		순차적으로 반복을 돌리면서 값을 대입
//		[표현법]
//		for(int i=0; i<arr.length; i++) {
//			for(int j=0; j<arr[i].length; j++) {
//				값을 대입, 출력, 누적 등을 쓰면 됨.
//			}
//		}
		// 값 대입
		int value = 0;
		// 0,1,2 : 3번
		for(int i=0; i<arr.length; i++) { 
			// 0,1,2,3,4 : 5번
			for(int j=0; j<arr[i].length; j++) { 
				value++;
				arr[i][j]=value;
			}
		} // 총 15번 반복
		
		// 값 출력
		for(int i=0; i<arr.length; i++) {
			for(int j=0; j<arr[i].length; j++) {
				System.out.printf("%-2d ",arr[i][j] );
			}
			System.out.println();
		}
	}

	public void method3() {
//		1차원 배열의 선언과 동시에 초기화
//		int[] iArr = {1,2,3,4,5};
		
//		2차원 배열의 선언과 동시에 초기화
		int[][] iArr = {{1,2,3,4,5},
					   {6,7,8,9,10},
		               {11,12,13,14,15}};
//		출력
		for(int i=0; i<iArr.length; i++) {
			for(int j=0; j<iArr[i].length; j++) {
				System.out.printf("%-2d ",iArr[i][j]);
			}
			System.out.println();
		}
	}

	public void method4() {
//		2행, 3열짜리 2차원 배열 
//		0번째 행은 국어점수
//		1번째 행은 수학점수를 입력받아봄
		Scanner sc = new Scanner(System.in);
		int[][] scores = new int[2][3];
		
//		값 대입
		for(int i=0; i<scores.length; i++) {
			for(int j=0; j<scores[i].length; j++) {
				if(i==0) { // 국어 점수
					System.out.print("국어 점수 : ");
				}else { // 수학 점수
					System.out.print("수학 점수 : ");
				}
				scores[i][j] = sc.nextInt();
				sc.nextLine();
			}
		}
		
		for(int i=0; i<scores.length; i++) {
			if(i==0) {
				System.out.print("국어 점수들 : ");
			}else {
				System.out.print("수학 점수들 : ");
			}
				for(int j=0; j<scores[i].length; j++) {
						System.out.print(scores[i][j]+" ");
				}
				System.out.println();
		}
	}

	public void method5() {
//		1차원 배열을 2개 만들어서
//		각각 국어점수, 수학점수를 입력받아
//		출력하기
		
//		1차원 배열 선언 및 할당
		Scanner sc = new Scanner(System.in);
		int[] korean = new int[3];
		int[] math = new int[3];
		
//		1차원 배열 값 대입
		for(int i=0; i<korean.length;i++) {
			System.out.print("국어 점수 : ");
			korean[i]=sc.nextInt();
			sc.nextLine();
		}
		for(int j=0; j<korean.length;j++) {
			System.out.print("수학 점수 : ");
			math[j]=sc.nextInt();
			sc.nextLine();
		}
//		1차원 배열 값 출력
		System.out.print("국어 점수들 : ");
		for(int i=0; i<korean.length; i++) {
			if((i+1)%3==0) {
				System.out.print(korean[i]+" ");
			}else {
				System.out.print(korean[i]+", ");
			}
		}
		System.out.println();
		System.out.print("수학 점수들 : ");
		for(int j=0; j<korean.length; j++) {
			if((j+1)%3==0) {
				System.out.print(math[j]+" ");
			}else {
				System.out.print(math[j]+", ");
			}
		}
	}
// 이 외에도, 각각의 행의 열의 개수를 달리하는
//	 가변배열이라는 것도 있음. 
	
}

0개의 댓글