[KOSTA JAVA] #Day 3 (Memory using structure, Heap, Stack, 참조 변수, null, String, Array, 열거타입, Exam Quiz)

0f1c04·2021년 2월 19일
0

KOSTA JAVA TIL

목록 보기
3/11
post-thumbnail

신용권님의 "이것이 자바다" 공부 기록
책을 보면서 내용을 정리했습니다. 이것이 자바다 커뮤니티 : https://cafe.naver.com/thisisjava

  1. 데이터 타입 분류
  2. 메모리 사용 영역
  3. 참조 변수의 ==, != 연산
  4. null과 NullPointerException
  5. String 타입
  6. 배열 타입
  7. 열거 타입

#Day 2 Review

package com.kosta.day03;

import java.util.Scanner;

public class Review {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("[더 입력할 점수가 없으면 -1을 입력]");
		double result = 0;
		int count = 0;
		
		while(true) {
			System.out.print("점수를 입력하십시오 : ");
			double num = sc.nextDouble();
			if(num == -1) break;
			result += num;
			count++;
		}
		sc.close();
		
		double avg = result / count;
		System.out.println("입력된 점수들의 수 : " + count);
		System.out.println("점수들의 평균(double value) : " + avg);
		System.out.println("점수들의 평균(int value) : " + (int)avg);
	}
}
  • Scanner, 형변환, 반복문, 조건문 복습

1. 데이터 타입 분류

1-1. 변수의 메모리 사용

  • 기본 타입 변수 - 실제 값을 변수안에 저장
  • 참조 타입 변수 - 주소를 통해 객체 참조

2. 메모리 사용 영역

2-1. JVM이 사용하는 메모리 영역

OS에서 할당 받은 메모리 영역(Runtime Data Area)을 세 영역으로 구분

  • 메소드 영역
    • JVM 시작할 때 생성
    • 로딩된 클래스 바이트 코드 내용을 분석 후 저장
  • 힙 영역
    • JVM 시작할 때 생성
    • 객체/배열 저장
    • 사용되지 않는 객체는 Garbage Collector가 자동 제거 (dangling된 객체를 제거)
  • JVM 스택
    • 스레드 별 생성
    • 메소드 호출할 때마다 Frame을 스택에 추가(push)
    • 메소드 종료하면 Frame 제거(pop)

JVM의 stack과 frame 자세한 내용

johngrib.github.io/wiki/jvm-stack/


JVM stack과 frame
johngrib.github.io


3. 참조 변수의 ==, != 연산

3-1. 변수의 값이 같은지 다른지 비교

  • 기본 타입 : 변수의 값이 같은지 다른지 조사
  • 참조 타입 : 동일한 객체를 참조하는지 다른 객체를 참조하는지 조사
package com.kosta.day03;

public class 참조연습 {
	public static void main(String[] args) {
		sample();
	}

	private static void sample() {
		String s1 = "홍길동";
		String s2 = "홍길동";
		String s3 = new String("홍길동");
		String s4 = new String("홍길동");
		// s1, s2는 주소가 같음, s3, s4는 주소가 다름
		System.out.println(s1 == s2); // true
		System.out.println(s3 == s4); // false
		
		System.out.println(System.identityHashCode(s1)); //366712642
		System.out.println(System.identityHashCode(s2)); //366712642
		System.out.println(System.identityHashCode(s3)); //1829164700
		System.out.println(System.identityHashCode(s4)); //2018699554
	}
}

4. null과 NullPointerException

4-1. null (널)

  • 변수가 참조하는 개체가 없을 경우 초기값으로 사용 가능
  • 참조 타입의 변수에만 저장가능
  • null로 초기화된 참조 변수는 스택 영역 생성
  • ==, != 연산 가능

4-2. NullPointerException의 의미

  • 예외(Exception) : 사용자의 잘못된 조작이나 잘못된 코딩으로 인해 발생하는 프로그램 오류
  • NullPointerException : 참조 변수가 null 값을 가지고 있을 때, 객체의 필드나 메소드를 사용하려고 했을 때 발생
private static void sample3() {
		// 참조형은 일반적으로 null로 초기화
		String s = null;
		System.out.println(s);
		System.out.println(s.length()); //NullPointerException
	}


5. String 타입

  • 문자열 리터럴이 동일하다면 String 객체 공유
  • new 연산자를 이용한 String 객체 생성 시 힙 영역에 새로운 String 객체를 생성하고 주소를 리턴

6. 배열 타입

  • 같은 타입의 데이터를 연속된 공간에 저장하는 자료구조
  • 각 데이터 저장 위치는 인덱스 부여해서 접근

6-1. 배열의 장점

  • 중복된 변수 선언을 줄일수 있다.
  • 반복문 이용해 요소들을 쉽게 처리할 수 있다.

6-2. 배열 선언

  • 배열을 사용하기 위해 배열 변수 선언
  • 배열 변수는 참조 변수이므로 생성되기 전 null로 초기화 가능
  • 배열 변수가 null값을 가진 상태에서는 항목에 접근이 불가하다. (NullPointerException 발생)

6-3. 값 목록으로 배열 생성

  • 변수 선언과 동시에 값 목록 대입
  • 변수 선언 후 값 목록 대입

6-4. new 연산자로 배열 생성

  • 배열 생성시 값 목록을 가지고 있지 않음
  • 향후 값들을 저장할 배열을 미리 생성하고 싶은 경우

6-5. 타입 별 항목의 기본값


6-6. 배열의 길이

  • 배열에 저장할 수 있는 전체 항목 수
  • 코드에서 배열의 길이 얻는 방법
배열변수.length;

int[] intArray = {10, 20, 30};
int num = intArray.length;
  • 배열의 길이는 읽기 전용
intArray.length = 10; // 잘못된 코드
  • 배열의 길이는 for문의 조건식에 주로 사용
int[] scores = {83, 90, 87};

int sum = 0;
for(int i = 0; i < scores.length; i++) {
	sum += scores[i];
}
System.out.println("총합 : " + sum);

6-7. 커맨드 라인 입력

  • 배열의 선언과 사용

6-8. 다차원 배열

  • 2차원 배열 이상의 배열 : 수학의 행렬과 같은 자료 구조
  • 자바는 1차원 배열을 이용해 2차원 배열 구현
int[][] scores = new int[2][3];

scores.length		// 2 (배열 A의 길이)
scores[0].length	// 3 (배열 B의 길이)
scores[1].length	// 3 (배열 C의 길이)

6-9. 객체를 참조하는 배열

  • 각 항목에 객체의 번지를 가진다.
String[] strArray = new String[3];
strArray[0] = "java";
strArray[1] = "C++";
strArray[2] = "C#";

6-10. 배열 복사

  • 배열을 한 번 생성하면 크기 변경 불가하다.
  • 더 많은 저장 공간이 필요하다면 보다 큰 배열을 선언하고 항목 값들을 복사해야한다.

배열 복사 방법

  • for문 이용
  • System.arrayCopy() 메소드 이용
  • Arrays 클래스 이용
private static void method4() {
		// 배열복사
		int[] arr1 = new int[] { 100, 99, 70, 88, 95 };

		// 1. for 사용
		int[] arr2 = new int[arr1.length];
		for (int i = 0; i < arr1.length; i++) {
			arr2[i] = arr1[i];
		}
		arr1[0] = 200;
		System.out.println(Arrays.toString(arr1));
		System.out.println(Arrays.toString(arr2));

		// 2. System.arraycopy 사용
		int[] arr3 = new int[arr1.length];
		System.arraycopy(arr1, 0, arr3, 0, arr1.length);
		System.out.println(Arrays.toString(arr1));
		System.out.println(Arrays.toString(arr3));
		
		// 3. Arrays 클래스 사용
		int[] arr4 = Arrays.copyOf(arr1, arr1.length);
		System.out.println(Arrays.toString(arr1));
		System.out.println(Arrays.toString(arr4));
	}

6-11. 향상된 for문 (확장 for문)

  • 배열 및 컬렉션의 항목 요소를 순차적으로 처리한다.
  • 인덱스를 이용하지 않고 바로 항목 요소를 반복한다.
int[] scores = {95, 71, 84, 93, 87};

int sum = 0;
for(int score : scores) {
	sum = sum + score;
}

7. 열거 타입

7-1. 열거 타입 선언

  • 파일 이름과 동일한 이름으로 다음과 같이 선언 (첫 글자 대문자)
public enum 열거타입이름 {...}
  • 한정된 값인 열거 상수 정의
    • 열거 상수 이름은 관례적으로 모두 대문자로 작성
    • 다른 단어가 결합된 이름일 경우 관례적으로 밑줄(_)로 연결
public enum Week {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, ...}

public enum LoginResult {LOGIN_SUCCESS, LOGIN_FAILED}

7-2. 열거 타입 변수

  • 열거 타입 변수 선언
열거타입 변수;

Week today;
Week reservationDay;
  • 열거 상수 값 저장 - 열거 타입 변수값은 열거 상수 중 하나
열거타입 변수 = 열거타입.열거상수;

Week today = Week.SUNDAY;
  • 열거 타입 변수는 참조 타입이므로 null 값 저장 가능
Week birthday = null;

7-3. 열거 객체의 메소드

  • 열거 객체는 열거 상수의 문자열을 내부 데이터로 가지고 있다.
  • 열거 타입은 컴파일 시 java.lang.Enum 클래스를 자동으로 상속하므로 java.lang.Enum 클래스의 메소드를 사용 가능하다.

5장 문제풀이

package com.kosta.day03;

import java.util.Scanner;

public class Exercise {

	public static void main(String[] args) {
		// quiz6();
		// quiz7();
		// quiz8();
		quiz9();
	}

	private static void quiz9() {
		// 키보드로부터 학생 수와 각 학생들의 점수를 입력받아서, 최고 점수 및 평균 점수를 구하
		boolean run = true;
		int studentNum = 0;
		int[] scores = null;
		Scanner sc = new Scanner(System.in);

		while (run) {
			System.out.println("----------------------------------------------");
			System.out.println("1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료");
			System.out.println("----------------------------------------------");
			System.out.print("선택> ");

			int selectNo = sc.nextInt();

			if (selectNo == 1) {
				System.out.print("학생수> ");
				studentNum = sc.nextInt();
			} else if (selectNo == 2) {
				scores = new int[studentNum];
				for (int i = 0; i < studentNum; i++) {
					System.out.print("scores[" + i + "]: ");
					scores[i] = sc.nextInt();
				}
			} else if (selectNo == 3) {
				for (int i = 0; i < studentNum; i++) {
					System.out.println("scores[" + i + "]:" + scores[i]);
				}
			} else if (selectNo == 4) {
				int sum = 0, count = 0, max = 0;
				double avg = 0.0;
				for (int i = 0; i < studentNum; i++) {
					sum += scores[i];
					count++;
					if (max < scores[i]) max = scores[i];
				}
				avg = (double) sum / count;
				System.out.println("최고 점수: " + max);
				System.out.println("평균 점수: " + avg);
			} else if (selectNo == 5) {
				run = false;
			}
		}
		sc.close();
		System.out.println("프로그램 종료");
	}

	private static void quiz8() {
		// 주어진 배열의 전체 항목의 합과 평균값을 구하라
		int[][] array = { { 95, 86 }, { 83, 92, 96 }, { 78, 83, 93, 87, 88 } };
		int sum = 0;
		double avg = 0.0;

		int count = 0;
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				sum += array[i][j];
				count++;
			}
		}
		avg = (double) sum / count;

		System.out.println("sum: " + sum);
		System.out.println("avg: " + avg);
	}

	private static void quiz7() {
		// 주어진 배열의 항목에서 최대값을 구하라
		int max = 0;
		int[] array = { 1, 5, 3, 8, 2 };

		for (int i = 0; i < array.length; i++) {
			if (array[i] > max)
				max = array[i];
		}

		System.out.println("max : " + max);
	}

	private static void quiz6() {
		// array.length 값과 array[2].length값을 구하라
		int[][] array = { { 95, 86 }, { 83, 92, 96 }, { 78, 83, 93, 87, 88 } };
		System.out.println(array.length + " " + array[2].length);
	}
}
  • p.182~184 확인문제 풀이코드
profile
라면 먹고 싶다. 두 개 끓여서 혼자 먹고 싶다. - 임덕배 (1997. 06 ~ )

0개의 댓글