[Java #6 / 250310] 배열

temi·2025년 3월 10일

Java

목록 보기
6/15

학원에서 학습한 내용을 개인정리한 글입니다.


오늘의 진도


수업

배열

  • 같은 자료형의 변수를 하나의 묶음으로 다루는 것
  • 인덱스 번호가 0부터 시작
  • 참조 변수
    • Heap 영역에 할당되며 배열 공간의 주소를 저장
    • 인덱스를 참조하는 방식으로 값 처리
  • 변수 선언
    • 자료형[] 배열명;
      • e.g. int[] a= new int[3];

  • 선언과 동시에 초기화
    • e.g. int[] arr = {1, 2, 3, 4, 5};
//배열을 저장하는 변수를 선언
//자료형[] 변수명;
int[] numbers;

//배열 변수에는 타입에 맞는 변수를 생성해서 대입 -> 할당
//int형 변수를 3개 생성
numbers = new int[3];

//생성된 배열에 접근  
//배열변수명[인덱스]
System.out.println("0: " + numbers[0]);
System.out.println("1: " + numbers[1]);
  • 배열 저장소에 값 저장
//배열 저장소에 값 저장하기 
numbers[0] = 100;
numbers[1] = 99;
System.out.println("0: " + numbers[0]);
System.out.println("1: " + numbers[1]);
  • 선언된 배열 변수 타입과 할당한 배열 타입은 일치해야함
//선언된 배열 변수 타입과 할당한 배열의 타입은 일치해야 한다.
double[] height = new double[5];    
char[] alphabet = new char[3];
String[] strArr = new String[5];
  • 자료형 별 기본값
//자료형별 기본값
//정수형(byte. short, int, long): 0
//실수형(float, double): 0.0
//문자(char) : ' '
//문자열(String): null;
System.out.println("double: "+ height[0]);
System.out.println("char: "+ alphabet[0]);
System.out.println("string: "+ strArr[0]);
  • 배열의 길이를 알려주는 변수 활용
    • 배열명.length -> 변수(필드)에 값을 출력
    • String.length() -> 메소드

//배열의 길이(저장소갯수)를 알려주는 변수
System.out.println("friends: "+ friends.length);

for (int i = 0; i < friends.length; i++) {
	System.out.println(i + "friends: "+ friends[i]);
}
  • 배열과 동시에 초기화
    • 자료형[] 변수명 = {리터럴, 리터럴 ...}
      • e.g. char[] arrChar = {'가', '나', '다'};

char[] arrChar = {'가', '나', '다'};
for (int i = 0; i < arrChar.length; i++) {
	System.out.println(i + " arrChar: "+ arrChar[i]);
}

double[] height = new double[] {180.5, 190.2, 177.3, 164.2};
for(int i = 0; i < height.length; i++) {
	System.out.print("[" + i + "]: "+ height[i] + " ");
}
System.out.println();
  • 배열은 한번 선언된 길이를 변경할 수 없음

    • e.g.arrChar[3] = 'd'; 안됨!
  • 만약 배열 길이를 늘려야할 때는 새로 더 긴 배열을 만들어서 복제해서 사용

  • 배열 정렬

    • 데이터 크기에 따라 오름차순, 내림차순으로 순서를 변경
	
		//오름차순 출력
		for (int i = 0; i < height.length; i++) {
			System.out.println(i + ": " + height[i]);
			for (int j = 0; j < height.length; j++) {
				if (height[i] < height[j]) {
					double temp = height[i];
					height[i] = height[j];
					height[j] = temp;
				}
			}
		}
		System.out.println(Arrays.toString(height));
sort 기능 쓰면됨..

얕은 복사

  • 주소값을 공유
int[] num = {1, 2, 3, 4, 5};
int[] copyNum = num;

System.out.println(num);
System.out.println(copyNum);

num[0] = 100;
//복사한 다음 num[0]을 변경했지만 copyNum[0]에도 동일한값이 나온다.
System.out.println(copyNum[0]);

깊은 복사

  • 사본으로 생성

int[] deepCopyNum = new int[num.length];
for (int i = 0; i < num.length; i++) {
	deepCopyNum[i] = num[i];
}
num[1] = 200;
//deepCopyNum의 [1]값은 바뀌지않음
System.out.println("num: " + Arrays.toString(num));
System.out.println("copyNum: " + Arrays.toString(copyNum));
System.out.println("deepCopyNum: " + Arrays.toString(deepCopyNum));
  • 깊은 복사 기능 이용하기 (메소드)
    • System.arraycopy(1, 2, 3, 4, 5)
      • 1: 원본 배열 변수명
      • 2: 원본 배열 시작 인덱스 번호
      • 3: 사본 배열 변수명
      • 4: 사본 배열 시작 인덱스 번호
      • 5: 복사할 데이터 수
//깊은 복사 기능 이용하기 (메소드)
String[] names = {"a", "b", "c", "d", "e"};
String[] copyNames = new String[7];
System.arraycopy(names, 2, copyNames, 3, 2);
System.out.println("names: " + Arrays.toString(names));
System.out.println("copyNames: " + Arrays.toString(copyNames));

System.arraycopy(names, 0, copyNames, 0, names.length);
System.out.println("names: " + Arrays.toString(names));
System.out.println("copyNames: " + Arrays.toString(copyNames));

//완벽한 사본?
//clone()
//완전 동일한 배열 사본이 생성
String[] methodCopy = names.clone();
System.out.println("methodCopy: " + Arrays.toString(methodCopy));

실습

친구 3명 저장할수있는 변수를 선언, 저장소에 이름 저장 출력

//친구 3명 저장할수있는 변수를 선언, 저장소에 이름 저장 출력
//저장소에 이름 저장 후 출력
String[] friends = new String[3];
for (int i = 0; i < 3; i++) {
	System.out.print(i + " 친구 이름 입력: ");
	friends[i] = sc.next();
	System.out.println(i + "friends: "+ friends[i]);
}

숫자를 5개 저장하는 배열을 만들고 1-5까지 수를 저장 후 출력

int[] numberList = new int[5];
for (int i = 0; i < numberList.length; i++) {
	numberList[i] = i + 1;
}
for (int i = 0; i < numberList.length; i++) {
	System.out.println(i + " numberList: " + numberList[i]);
}

데이터 필터

	데이터 필터 -> 원하는 값을 조회할 때, 수정할 때
	수 10개를 저장하는 저장공간을 확보하고
	10개의 저장소에 랜덤으로 1~100까지의 숫자를 저장
	저장된 값중에서 50보다 큰 수가 몇개인지 출력
	50보다 큰 수는 "00개"
int[] numberList2 = new int[10];
int count = 0;
for (int i = 0; i < numberList2.length; i++) {
	numberList2[i] = rd.nextInt(100) + 1;
}

for (int i = 0; i < numberList2.length; i++) {
	if (numberList2[i] > 50) {
		count++;
		System.out.println(i + "번째: " + numberList2[i]);
	}
}
System.out.println("result: " + count + "개");

사용자가 찾는 성씨의 학생 구하기

  • 원래같으면 성과 이름을 분리해서 따로 변수를 만들어줬을 것 같은데, 실습 취지에 맞게 한번에 받음
    • 성과 이름이 몇글자일지 몰라서 분리하고싶음..
char findName = ' ';
int count = 0;
System.out.print("찾으려는 친구 성 입력: ");
findName = sc.next().charAt(0);

for (int i = 0; i < studentNameList.length; i++) {
	if (studentNameList[i].charAt(0) == findName) {
		count++ ;
		System.out.print("[" + i + "]: "+ studentNameList[i] + " ");
	}
}
System.out.println();
System.out.println("result: " + count + "명");

height에 저장된 값 중. 최대값, 최소값 구하기


//동일값일 때 문제생길 때가 있어서 if만으로 줄 것?

double minHeight = 0.0d, maxHeight = 0.0d;
for (int i = 0; i < height.length; i++) {

	if (height[i] < minHeight) {
		minHeight = height[i];
	} else if (height[i] > maxHeight) {
		maxHeight = height[i];
	} else if (minHeight == 0.0d) {
		minHeight = height[i];
	}
}

2차원 배열

  • 자료형이 같은 1차원 배열의 묶음으로 배열 안에 다른 배열 존재
  • 할당된 공간마다 인덱스 번호 두 개 부여
  • 앞 번호는 행, 뒷 번호는 열 [0][0]
    • arr[m][n]
  • 행과 열이 주소값은 따로 잡혀있음.
  • 행, 열
//2차원 배열
//배열 저장소가 두개 연결되어 있는 구조

int[][] intArr;
intArr = new int[3][3];

System.out.println(intArr);
System.out.println(intArr[0]);
System.out.println(intArr[0][1]);
  • 선언과 동시에 초기화
String[][] strArr = {{"가","나","다"}, {"라","마","바"}};
strArr[0] = new String[] {"심심", "안심심", "배고픔"};
for(int i = 0; i < strArr.length; i++) {
	for(int j = 0; j < strArr[i].length; j++) {
		System.out.print(strArr[i][j] + " ");
	}
	System.out.println();
}

배열 데이터 탐색 (foreach)

  • for(변수 선언: 배열명) {로직}
  • foreach 안에서만 배열 값을 바꿀수있고,바깥에서는 배열값이 바뀌지않는다.
    //2차원 배열 사용
    char[][] chArr= {{'가', '다'},{'a', 'c'}};
    for(char[] arr:chArr) {
    	for (char c:arr ) {
    		System.out.print("[chArr] " + c +  "");
    	}
    	System.out.println();
    }

실습

정수 5개를 저장할 수 있는 배열에 1~10까지의 랜덤값을 저장

  • 조건 : 중복값 없이 저장

  • 중요하게 생각했던 건 random 숫자를 한번 돌릴 때마다 int형 배열 arr[i]가 전부 검색해서 중복을 찾아봐야한다, 였음.. 왜냐면 내가 너무 로직을 적다가 적다가 까먹어서 엄청 노트에 강조하고 손코딩을 했다 ㅠㅠ

  • int형 배열 arr[i]의 값이 0일 때, 중복이 카운트 됐을때 for문을 중단하고 빠져나왔다.

    • 이거..최적화한다고 한건데 별로 쓸모있는 것 같진않다..
  • flagNum으로 5개 숫자 차는거 카운트, 반복문

  • for문 중복으로 안썼다고좋아했는데 이중반복문이다.. (while for)

  • 중복 카운트가 없을 때 arr[i]에 값을 넣어주고 flagnum(반복문 카운트)를 올려준다

public void arrayRandomTest() {
	int[] arr = new int[5];
	int randNum = 0, flagNum = 0;
	
	while (flagNum < 5) {
		int count = 0;
		randNum = rd.nextInt(10) + 1;

		for (int i = 0; i < arr.length; i++) {
			if (arr[i] == 0) {
				break;
			} else if (arr[i] == randNum) {
				count++;
				break;
			}
		}
		if (count == 0) {
			arr[flagNum] = randNum;
			flagNum++;
		}
	}
}

위 문제의 피드백 버전

  • boolean 타입 배열[11]으로 중복체크
    • 나온 적이 있는 숫자를 true로 체크
      • e.g.: (!cache[randomNext])
    • 만약 중복되지 않는 숫자라면 int형 배열에 대입해주고, 갯수를 추가한다.
  • 진짜 이거보고 감탄했다..우와..우와……앞으로 나도 이런식으로 효율적으로 짜고싶다…
public void arrayRandomTest() {
	int[] result = new int[5];
	boolean[] cache = new boolean[11];
	
	int cursor = 0;
	
	while (cursor < 5) {
	    int next = random.nextInt(10) + 1;
	    if (!cache[next]) {
	        result[cursor] = next;
	        cache[next] = true;
	        cursor++;
	    }
	}
}

미리 준비

  • 깃허브 세팅 완료! 커밋 추가로 해보기

느낀점

  • 손코딩이 점점 다른 사람한테 설명할 수 있을 정도로 다듬어지고있어서 좋다! 더 연습해야지
  • 오늘은 간단한 코드말고 전부 손코딩으로 슈도코드 적고 진행해서 그런지 이전보다는 빨랐다!
  • 초코를 많이먹지말자.. 초코 너무 많이 먹어서 머리도 잘돌아가고 혈당스파이크도 왔다…
  • 마지막 실습예제 작성하면서 모자란걸 너무 느꼈다.. 연습해서 더 부끄럽지 않은 사람이 되어야지!!

profile
250304~

0개의 댓글