스택영역
: 호출됬을때 생성되고 자동으로 삭제되는 영역 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차원 배열
✅ 배열을 사용하는 이유
즉 배열이란 동일한 자료형의 변수를 하나의 묶음으로 다루는 것을 의미한다
✅ 배열의 특징?
✅ 배열 선언
(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)
💡 위 두가지 방식의 차이점?
✅ 배열길이 구하는 방법
-> 배열이름.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차원 배열의 특징
✅ 2차원 배열 선언
✅ 2차원 배열 할당
//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차원 배열 구조
✅ 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문을 사용
}