본문 바로가기

웹개발 수업/JAVA

[Day +8] 배열1

210702 금

 

<배열>

1. 배열

: 같은 자료형의 변수를 하나의 묶음으로 다루는 것

배열은 저장된 값마다 인덱스 번호가 0부터 시작하여 설정

1) 배열 선언과 할당

(1) 선언

자료형[]     배열명;

자료형       배열명[];

 

(2) 할당

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

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

 

2) 배열 저장 구조

: 배열은 참조 변수로 Heap영역에 할당되며 배열 공간의 주소를 저장

배열 공간의 주소를 이용해 인덱스를 참조하는 방식으로 값 처리

 

3) 배열 초기화

(1) 인덱스를 이용한 초기화

ex) arr[0] = 1;

arr[1] =2;

 

(2) for문을 이용한 초기화

ex) for(int i = 0; i < arr.length; i++) { arr[i] = i; }

 

*index가 순차적으로 증가함에 따라 초기화할 리터럴 값이 규칙적이라면 반복문을 통해 배열 초기화 가능

 

(3) 선언과 동시에 초기화

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

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

String fruit[] = {"사과", "포도", "참외"};

package com.kh.array;

import java.util.Random;
import java.util.Scanner;

public class A_Array {
	/* 배열 : "같은 자료형"의 변수를 하나의 묶음으로 다루는 것
	 * 		저장 된 값마다 인덱스가 지정되며 인덱스는 0부터 시작함
	 * 
	 */
	
	private int i;

	public void method1() {
		
		/* 1. 배열 선언
		 * 		자료형[] 배열명;
		 * 		자료형 배열명[];
		 */
		int[] arr;
		int arr2[]; //stack에 참조 변수만 생긴 것 = 배열을 선언했다
		
		/* 2. 배열 할당
		 * 	  배열명 = new 자료형[배열크기]
		 */
		
		arr = new int[5]; // => 20바이트 정도임.(1개에 4바이트)
		
		//선언과 할당을 동시에
		int[] arr1 = new int[5];
		
		/* 3. 초기화
		 * 	  배열명[인덱스] = 값;
		 */
		 arr[0] = 0;
		 arr[1] = 1;
		 arr[2] = 2;
		 arr[3] = 3;
		 arr[4] = 4;
		 
		 //***유의 사항 : String의 길이를 알아올 때는 문자열변수.length() <- 메소드 호출
		 //Array의 길이를 알아올 때는 배열변수.length <- 속성값
		 // () 붙이느냐 안 붙이느냐 주의할 것
		 for(int i = 0 ; i < arr1.length ; i++) {
			 //조건식이 배열 길이 미만이 되는 이유?
			 //인덱스는 0에서부터 배열길이 -1까지이므로
			 arr1[i] = i;
		 }
		
		 
		 //배열의 장점 : 인덱스의 위치, 값의 일정 규칙이 있으면 반복문을 사용가능하다
		 //초기화 된 값 출력 확인
		 System.out.println(arr[0]);
		 System.out.println(arr[1]);
		 System.out.println(arr[2]);
		 System.out.println(arr[3]);
		 System.out.println(arr[4]);
		 
		 //출력도 마찬가지로 0번 인덱스부터 배열길이 -1 인덱스까지 반복해서 출력
		 for(int i = 0 ; i < arr1.length ; i++) {
			 System.out.print(arr1[i]);
		 }
		 
		 
		 
		 
	}
	
	
	public void method2(){
		
		//변수 선언 : 메모르 공간에 값을 담을 박스를 만드는 과정
		//메모리의 stack영역에 할당됨
		int i;
		//stack에 i라는 값이 들어가게  된건
		
		
		// 배열 선언 : 변수 선언과 똑같이 stack 영역에 공간이 생기지만
		// 이 공간은 값을 담는 공간이 아니라 주소를 담는 공간이다 
        //=> 참조 변수 or 레퍼런스 변수라고 한다
		int[] iArr;
		
		//기본 자료형(boolean, char, byte, short, int, long, float, double)
		//으로 선언된 변수는 값을 담는다
		// 그 외의 타입(Array, String 등)으로 선언된 변수는 주소 값을 담는다.
		
		//배열 할당 : 배열 할당시에는 반드시 크기를 지정한다
		iArr = new int[5]; // new는 연산자라고 함, 4바이트 *5개 공간
		// => new 연산자를 통해 배열을 할당하게 되면 메모리의 heap 영역에 
		//	   해당 배열의 크기만큼의 공간이 만들어지고 그 공간의 주소 값을 
        //stack 영역의 레퍼런스 변수에 저장
		
		//따라서 배열에 값을 넣거나 수정할 때 해당 주소를 참조해서 사용
		// 배열 = 참조 변수이다
		
		// 위의 배열 선언과 할당을 동시에 해준 ver.
		int[] iArr2 = new int[5];
		System.out.println("iArr : " + iArr);
		System.out.println("iArr2 : " + iArr2); 
		
		/*iArr : [I@2a139a55
		 * iArr2 : [I@15db9742 이것은 주소다. 값이 아니다. stack에는 int값을 넣을 수 없다
		 */
		        

		// => 주소값을 출력한 것
		
		
		
	}
	
	public void method3() {
		char[] cArr = new char[5];
		int[] iArr = new int[3];
		// 선언 및 할당만 했을 뿐 명시적으로 초기화 한 적 없음
		// 현재 상태의 값 출력
		
		for(int i = 0; i < cArr.length; i++) {
			System.out.println(cArr[i]);
		}System.out.println("============================");
		for(int i = 0; i < iArr.length; i++) {
			System.out.println(iArr[i]);
		}
		/* 답
		 * (공백)
		 * (공백)
		 * (공백)
		 * ============================
			0
			0
			0
			*/
		
		
		/*int num;
		System.out.println(num);
		배열의 경우 지역변수와 달리 초기화하지 않아도 출력 됨
		
		
		heap영역은 값이 없는 공간이 존재할 수 없어 JVM이 자동으로 초기값 부여
		문자 : 공백, 숫자 : 0
		*/
		
	}
	
	public void method4() {
		//사용자에게 입력 받은 정수로 배열의 길이 지정해보기
		Scanner sc= new Scanner(System.in);
		
		System.out.print("새로 할당할 배열의 길이 : ");
		int size = sc.nextInt();
		
		// double 형 배열 dArr을 사용자가 입력한 size만큼 할당
		double[] dArr = new double[size];
		
		System.out.println("dArr : " + dArr);
		System.out.println("dArr의 길이 : " + dArr.length);
		System.out.println("dArr[0] : " + dArr[0]); // => 원래 값(기본 값)
		
		
		/*
		 * 새로 할당할 배열의 길이 : 100
			dArr : [D@74a14482
			dArr의 길이 : 100
			dArr[0] : 0.0 */
		
	}
	
	
	public void method5() {
		int[] iArr = new int[5];
		
		//2, 4, 6, 8, 10으로 배열 값 초기화 하고 싶다
		
		int value = 2;
		for(int i = 0 ; i< iArr.length ; i++ , value += 2) { // 이런식으로도 가능하다
			iArr[i] = value;
		//여기 좀 헷갈리네~ **	
		}
		//출력
		for(int i = 0 ; i < iArr.length ; i++) {
			System.out.println(iArr[i]);
		}
				
		
		System.out.println("iArr의 해쉬코드 값 : " + iArr.hashCode() );
		//hashCode -> 주소 값(16진수)의 10진수 값
		System.out.println("iArr의 길이 : " + iArr.length);
		
		
		//iArr[5] 12;
		//만약 추가로 값을 더 저장하고 싶어도 배열의 크기를 벗어나게 되면 오류가 발생한다.
		// **배열은 한번 지정한 크기를 변경할 수 없음***
		//=> 크기를 바꾸려고 한다면 다시 배열 크기를 지정해서 할당해주어야 함
		
		iArr = new int[10];
		//10개의 크기를 가진 배열을 heap영역에 새로 생성하고
		//새로 생성한 배열의 주소값을 iArr이라는 레퍼런스 변수에 덮어 씀
		
		System.out.println("========변경 후의 iArr========");
		System.out.println("iArr의 해쉬코드 값 : " + iArr.hashCode() );
		//hashCode -> 주소 값(16진수)의 10진수 값
		System.out.println("iArr의 길이 : " + iArr.length);
		
		/*iArr의 해쉬코드 값 : 705927765
		iArr의 길이 : 5
		 ========변경 후의 iArr========
		iArr의 해쉬코드 값 : 366712642
		iArr의 길이 : 10 */
		
		// GC가 0~4의 부분을 지워준다. 메모리 관리. //인강2 거의 뒷부분 다시 듣기
		//주소 값이 바뀐 것을 알 수 있음 
		//기존에 참조하고 있던 5개 길이의 배열으 어느 곳에서도 참조되고 있지 않으므로
		// => 일정 시간이 지나면 가비지 컬렉터(GC)가 더 이상 쓸모없다고 판단하여 지운다 
        //=> 자동 메모리 관리
		
		
		//10개 길이의 배열을 지우려면?
		iArr = null; 
		
		//*null
		//레퍼런스 변수 : 주소값 저장 변수 : 
		//레퍼런스 변수에 null이 대입되면 주소 값이 null로 바뀜
		//즉, 참조하는 주소가 없다는 의민
		//10개 길이의 배열을 참조한는 참조 변수가 사라져서 
        //역시 일정 시간이  지나면 GC가 삭제한다 
		System.out.println("========삭제 후의 iArr========");
		System.out.println("iArr의 해쉬코드 값 : " + iArr.hashCode() );
		//hashCode -> 주소 값(16진수)의 10진수 값
		System.out.println("iArr의 길이 : " + iArr.length);
		
		/* ========삭제 후의 iArr========
		java.lang.NullPointerException
		at com.kh.array.A_Array.method5(A_Array.java:222)
		at com.kh.arrayrun.ArrayRun.main(ArrayRun.java:10)
		
		이 상태 : 스택 영역에서 iArr = null로 바뀌어서 heap은 주소값을 받아올 수 없다. 
        그래서 실행 불가
		
		*NullPointerException 발생의미
		레퍼런스 변수가 아무것도 참조하고 있지 않고 
        null이라는 특수한 값을 가지고 있을 때 발생함
	*/
	}
	
	
	public void method6() {
		//배열 선언 및 할당과 동시에 초기화
		int[] iArr = {1, 2, 3, 4};
		//초기화  :초기 값을 작성해주는 것
		//중괄호 블럭을 사용하는 경우 new연산자를 사용하지 않아도 되며
		//값의 개수만큼 자동으로 크기가 할당 됨
		
		int[] iArr2 = new int[] {1, 2, 3, 4};
		
		//두 방법 모두 사용 가능하다.
		
		System.out.println("iArr의 길이 : " + iArr.length);
		System.out.println("iArr의 길이 : " + iArr2.length);
		
		/*답 iArr의 길이 : 4
		iArr의 길이 : 4 */
		
		System.out.println(iArr == iArr2);
		//iArr과 iArr2는 길이도 같고 값고 같지만 완전히 같다고는 할 수 없다.
		//왜냐하면 주소값이 다르게 만들어지잖아!!
		//레퍼런스 변수를 비교하면 주소 값이 다르므로 false가 나옴
		
		System.out.println(iArr[0] == iArr2[0]);
		//iArr[0]과 iArr2[0]의 값은 같나요 ? YES
		//특정 인덱스를 통해 값을 비교할 경우 1 == 1이므로 true가 나옴
		
		//예) 문자열의 경우 비교가 안된다고 언급했다. "a" == "a" 인가요?
		// 안된다. 그래서 equals를 사용했었잖아~
		
		
		
		
		
	}
	
	public void method7() {
		//String 문자열도 배열로 사용 가능
		String[] sArr = new String[5];
		
		//직접적인 초기화 전 출력 결과 확인
		//for(int i = 0 ; i < sArr.length;i++) {
			//System.out.println(sArr[i]);
		//}
		
		Scanner sc = new Scanner(System.in);
		//0번 인덱스부터 마지막까지 반복으로
		//사용자에게 문자열 력 받고 해당 인덱스에 사용자가 입력한 값 넣기
		for(int i = 0 ; i < sArr.length ; i++) {
			System.out.print("문자열 입력 : ");
			sArr[i] = sc.nextLine();	
		}
		//입력 받은 값 출력
		for(int i = 0 ; i < sArr.length ; i++) {
		System.out.println(sArr[i]);
		}
	}
	
	
	public void method8() {
		//사용자에게 5명의 키 정보를 입력 받아 배열에 담아 두고
		//반복문을 통해 5명 키의 총합, 평균 구하기
		
		Scanner sc = new Scanner(System.in);
		double[] height = new double[5];
		double sum = 0;
		
		//배열 처음부터 끝까지 반복
			// 키 입력 받기
			// 입력 받은 값 배열에 대입
			// 합계
		
		for(int i = 0 ; i < height.length ; i++){
			System.out.print("키 입력 : ");
			height[i] = sc.nextDouble();
			
			sum += height[i];
			
		} 	
		System.out.println("총합 : " + sum);
		System.out.println("평균 : " + sum / height.length);
}

	
	public void method9() {
		
		//사용자에게 입력 받은 정수 크기 만큼의 int 배열 할당 후
		// 1~100 사이의 랜덤 값 발생시켜서 대입 후 출력
		// 방법1. java.lang.Math 클래스의 random 메소드 이용
		// 방법2.  java.util.Random 클래스
		Random ran = new Random();
		
		System.out.println("int 범위의 난수 : " + ran.nextInt());
		System.out.println("1~100 범위의 난수 : " + ran.nextInt(100) + 1);
						//0~99가 범위이므로 1을 더해줘야 0~100이된다.
		
		/* 답
		 * int 범위의 난수 : 830189433
		1~100 범위의 난수 : 221 */
		
		Scanner sc = new Scanner(System.in);
		System.out.print("정수 입력 : ");
		int size = sc.nextInt();
		
		int[] arr = new int[size];
		
		for(int i = 0 ; i < arr.length ; i++) {
			arr[i] = ran.nextInt(100) + 1;
			System.out.print(arr[i] + " ");
		}
		
	}
	
	public void method10() {
		
		//사용자에게 자유롭게 정수 값 입력을 받은 뒤 배열에 초기화
		//입력 받은 값 중 최소값 / 최대값 구하기
		//1 1000 -50 77 65 
		
		Scanner sc = new Scanner(System.in);
		int[] arr = new int[5];
		//각 인덱스에 사용자로부터 값 입력 받기
		for(int i = 0 ; i < arr.length; i++) {
			System.out.print(i+1 + "번째 입력 : ");
			arr[i] = sc.nextInt();
		
		}
		//arr[0]으로 최대값과 최솟값을 담을 변수를 초기화
		int max = arr[0];
		int min = arr[0];
		
		//1번 인덱스부터 배열 끝까지 비교(0번 인덱스는 max, min에 대입했으므로)
		for(int i = 1 ; i < arr.length ; i++) {
			if(max < arr[i]) 
				max = arr[i];
				if(min > arr[i])
					min = arr[i];
		}
		System.out.println("최대값 : " + max);
		System.out.println("최소값  : " + min);
	}
	
	
	
}
package com.kh.arrayrun;

import com.kh.array.A_Array;
import com.kh.array.B_ArrayCopy;
import com.kh.array.C_ArraySort;
import com.kh.array.D_Overlap;

public class ArrayRun {

	public static void main(String[] args) {
		
		//A_Array a = new A_Array();
		//a.method9();
		
		//B_ArrayCopy b = new B_ArrayCopy();
		//b.method4();
		
		//C_ArraySort c = new C_ArraySort();
		//c.method5();
		
		D_Overlap d = new D_Overlap();
		d.method2();

	}

}

'웹개발 수업 > JAVA' 카테고리의 다른 글

[Day +11]객체 / 객체지향언어, 클래스, 캡슐화, 추상화, 접근 제한자, 필드  (0) 2021.07.11
[Day +9]배열2  (0) 2021.07.11
[Day +7]분기문  (0) 2021.07.11
[Day +6]반복문  (0) 2021.07.11
[Day +5]조건문  (0) 2021.07.11