자바 프로그래밍 (배열)

최주영·2023년 3월 13일
0

자바

목록 보기
5/30

스택영역 : 호출됬을때 생성되고 자동으로 삭제되는 영역 ex) 변수

힙영역 : 개발자가 할당하는 영역이고 개발자가 직접 삭제해야하지만 GC(가비지컬렉션)이 있어서 주기적으로 알아서 삭제됨 ex) 배열

new 연산자 : 객체를 힙이라는 메모리 영역에 메모리 공간을 할당해주고 메모리주소를 반환한 후 생성자를 실행시켜준다

// new 연산자 작동 원리 예시
public class Main {
	public class Main {
	
	public static void main(String[] args) {
		String str = new String("string"); // 변수는 Stack 영역에 할당됨
         // new String으로 생성된 문자열값이 Heap영역의 메모리 공간을 할당받아 str이라는 변수가 그 메모리주소를 가르키고 있음 (참조)
		String str2 = new String("string"); // 처음에 생성한 "string"을 가르키지 않고 힙 메모리에 새로운 영역을 할당받아 생성함
	}
}


1차원 배열

✅ 배열을 사용하는 이유

  • 동일한 타입의 변수를 여러개 만드는게 불편해서 배열을 사용함
    ex) int형 변수 10개가 필요 -> 변수 10개 만들기 불편 -> 배열을 만들면 편함!

배열이란 동일한 자료형의 변수를 하나의 묶음으로 다루는 것을 의미한다


✅ 배열의 특징?

  • 배열의 저장구조는 선형구조를 갖는다
  • 선형구조이기에 저장순서와 저장소를 지칭하는 번호(index)를 가진다

✅ 배열 선언
(1) : 자료형[] 배열명;
(2) : 자료형 배열명[];

ex) int[] iarray;
    double darray[];

✅ 배열 할당
(1) : 자료형[] 배열명 = new 자료형[배열크기];
(2) : 자료형 배열명[] = new 자료형[배열크기];

ex) int [] iarray = new int[3];
    double darray[] = new double[5];

💡 배열을 할당하고 값을 초기화 하지 않으면?

  • 정수형 배열 초기값 : 0
  • 실수형 배열 초기값 = 0.0
  • 문자열 배열 초기값 = null
  • 문자형 배열 초기값 = ''


✅ 배열 선언과 동시에 초기화
(1) : 자료형[] 배열명 = {값};
(2) : 자료형 배열명[] = new 자료형{값};

ex) int [] iarray = {1,2,3};   //(1)
    int [] iarray = new int[]{1,2,3}; //(2)

💡 위 두가지 방식의 차이점?

  • (1)은 배열선언과 동시에만 초기화할 수 있음
    // ex) alpha = {'가','나','다','라'}; (사용불가)
  • (2)는 다른라인에서도 초기화 가능
    //ex) alpha = new char[]{'가','나','다','라'}; 사용가능

배열길이 구하는 방법

-> 배열이름.length;

int [] iarray = new int[3];
int len = iarray.length;  // len = 3

💡 배열은 한번 선언된 길이는 변경되지 않는다.

	 String[] names2 = new String[3];
	 names2[0] = "유병승";
	 names2[1] = "홍길동";
	 names2[2] = "피카추";
    //names2[3] = "리자몽"; // 자동으로 길이가 증가하지 않는다. ❌

배열의 복사
종류 : 얕은복사, 깊은복사

  • 얕은 복사 : 원본 값을 공유하는 방식 = 하나의 객체를 두 변수가 참조하는 것
int[] num = {1,2,3,4,5};
		//얕은복사 -> 주소를 복사해줌
		int[] copynum = num;
		System.out.println(num);
		System.out.println("num "+Arrays.toString(num));
		System.out.println("copynum "+Arrays.toString(num));
		System.out.println("num[0] : "+num[0]);  // 0
		System.out.println("num[0] : "+copynum[0]); //0
		// 주소값을 공유하기 때문에 저장소가 한개임!
		num[0] = 100;
		System.out.println("num[0] : "+num[0]); // 100
		System.out.println("num[0] : "+copynum[0]); // 100

📌 즉! 주소값을 공유했기 때문에 값을 변경하면 모두 바뀜!

  • 깊은 복사 : 새로운 배열 객체를 생성하여 기존 배열의 데이터를 복사
		int[] num = {1,2,3,4,5};
		int[] deepCopy = new int[num.length];
		for(int i=0; i<num.length; i++) {
			deepCopy[i] = copyNum[i];
		}
		System.out.println("num : " + Arrays.toString(num)); // 1,2,3,4,5
		System.out.println("deepCopy : " + Arrays.toString(deepCopy)); //1,2,3,4,5
		num[1] = 200;
		System.out.println("num : " + Arrays.toString(num)); // 1,200,3,4,5
		System.out.println("deepCopy : " + Arrays.toString(deepCopy)); // 1,2,3,4,5

📌 깊은 복사는 새로운 배열객체를 만들었기 때문에 원본이 바뀌어도 복사본은 바뀌지 않음!

배열에서 자주 사용하는 함수

  • copyof() : 특정 배열의 원하는 길이만큼 새로운 배열로 복사하는 함수

    새로운 배열 = Arrays.copyof(원본 배열, 원본 배열에서 복사하고 싶은 요소들의 길이);

  • clone() : 깊은 복사할 때 사용하는 함수

  • arraycopy() : 5가지 인수가 들어있는 함수로 여러가지 조건을 따져서 복사하는 함수

  • Arrays.toString(배열이름) : 배열 자체로 요소 모두 출력

  • System.arraycopy((1),(2),(3),(4),(5))
    // (1) : 원본배열
    // (2) : 원본배열의 시작인덱스
    // (3) : 복사될 배열
    // (4) : 복사될배열의 시작인덱스
    // (5) : 복사할 데이터 수(길이)
    💡 두번째 네번째에 원본과 복사된 배열의 길이는 같아야함!

// 예시 
// 		Arrays 클래스에서 제공하는 copyof() 기능 이용하기
		int[] num = { 1, 2, 3, 4, 5 };
		int[] copynum = num;
        
		int[] copy2 = Arrays.copyOf(num, num.length);
		System.out.println("cop2" + Arrays.toString(copy2)); // [200,2,3,4,5]
		int[] copy3 = Arrays.copyOf(num, 2);
		System.out.println("cop3" + Arrays.toString(copy3)); // [200,2]

		// 배열전체를 깊은복사할때는 clone() 이용해도된다.
		copy3 = num.clone(); // copy3은 2개 요소였는데 5개로 변함
		System.out.println("cop3" + Arrays.toString(copy3)); // [200,2,3,4,5]
        
        
        String[] names = { "유병승", "홍길동", "김유신" };
		String[] extend = new String[names.length + 5];
		System.arraycopy(names, 0, extend, 0, 2);
		for (int i = 0; i < extend.length; i++) {
			System.out.print(extend[i] + " "); // 유병승 홍길동 null null null null null null
		}
		System.out.println();
        

✅ 내장 랜덤 함수 : Math.random()
기본 범위는 0.0 ~ 1.0 범위이고
ex) 1~45 범위로 만들기

(int)(Math.random()*45)+1;  //  원하는 크기-1 만큼까지 곱해준 후 더해주기

2차원 배열

2차원 배열의 특징

  • 배열저장소 두 개가 연결되어있는 구조
  • 저장소는 바둑판처럼 저장구조를 가진다
  • 선언, 할당, 초기화는 1차원 배열과 비슷하다

2차원 배열 선언

  • 자료형[][] 배열명; -----> 📌 주로 이방법이 많이 쓰임!
  • 자료형 배열명[][]; -----> C언어에서는 이 방법으로 쓰다보니 이렇게 쓰는 습관이 있음..
  • 자료형[] 배열명[];

2차원 배열 할당

  • 자료형[][] 배열명 = new 자료형[행크기][열크기];
  • 자료형 배열명[][] = new 자료형[행크기][열크기];
  • 자료형[] 배열명[] = new 자료형[행크기][열크기];
  //ex)
	  int[][] arr = new int[3][4];
	  int arr[][] = new int[3][4];

2차원 배열 선언과 동시에 초기화

 // ex)
 int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}}; 
 int[][] arr = new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}};
 String fruit[][] = {{"사과", "딸기", "석류"}, {"바나나", "참외", "레몬"}}; // 문자열도 정수형과 동일

2차원 배열 구조

  • arr 변수는 arr[i]의 주소값을 찾아가고 arr[i]는 arr[i][j]의 주소 값을 찾아간다

forEach

  • 문법

    for(자료형 변수명 : 배열명 || CollectionFramwork) { }

		System.out.println("===== forEach문을 이용해서 출력 =====");
		for(int d : intArr) { // 변수 d로 intArr의 요소들을 출력!
			// if문 병행
			if(d % 2 == 0) {
				System.out.println(d);
			}
		}
        
        
        String[] hobby = {"농구", "자전거", "게임", "코딩"};
		for(String h : hobby) { // forEach에서의 변수가 지역변수이기 때문에
			if(h.equals("코딩")) h="운동"; //forEach문은 배열에 있는 값을 수정할 때는 사용할 수 없다. 
			System.out.println(h); // 따라서 위치나 값을 수정할 때 기본 for문을 사용
		}
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글