// 깊은 복사 메서드
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 2. Arrays.copyOf() 메서드
int[] a = { 1, 2, 3, 4 };
int[] b = Arrays.copyOf(a, a.length); // 배열과 함께 length값도 같이 넣어줍니다.
}
}
Collection
List
리스트는 크기가 가변적으로 늘어나는 동적배열이다.
ArrayList<Integer> intList = new ArrayList<Integer>(); // 선언과 동시에 생성 크기 지정x
intList.add(99);
intList.add(50);
intList.add(12); // 값이 추가되면서 크기가 늘어난다.
System.out.println(intList.get(1));
intList.set(1, 77); // 값을 수정
System.out.println(intList.get(1));
ArrayList<Integer> intList = new ArrayList<Integer>(); // 선언과 동시에 생성
intList.add(99);
intList.add(50);
intList.add(12);
System.out.println(intList.get(0));
intList.remove(0);
System.out.println(intList.get(0));
결과 : 99
50 // remove로 값을 제거하면 뒤에 있던 값들이 앞으로 땡겨진다.
Stack
값을 수직으로 쌓아놓고 넣었다가 빼서 조회하는 형식으로 데이터를 관리하는 자료형
LIFO “나중에 들어간 것이 가장 먼저 나온다(Last-In-First-out)”
Stack<Integer> intStack = new Stack<>();
intStack.push(29);
intStack.push(7);
intStack.push(1004); // 값을 넣어줌
while (!intStack.isEmpty()){
System.out.println(intStack.pop()); // 맨 위에 값을 꺼낸다.
}
// 결과 :
1004
7
29
Set
순서가 없고 자료의 중복을 허용하지 않는 집합으로 생성자가 없어 생성자가 존재하는 HashSet 클래스를 이용해서 생성한다.
선언 : Set<Integer> intSet
생성 : new HashSet<Integer>()
추가 : intSet.add({추가할 값})
조회 : intSet.get({조회 할 순번})
삭제 : intSet.remove({삭제할 값})
포함확인 : intSet.contains({포함확인 할 값}) - 해당값이 포함되어 있는지 boolean 값으로 응답
Map
key-value 구조로 key값은 중복을 허용하지 않는다.
선언 : Map<String, Integer> intMap
생성 : new HashMap<>()
추가 : intMap.put({추가할 Key값},{추가할 Value값})
조회 : intMap.get({조회할 Key값})
전체 key 조회 : intMap.keySet() - Map의 모든 Key를 모아서 Set 자료형으로 리턴
전체 value 조회 : intMap.values() - Map의 모든 Value를 모아 Set 자료형으로 리턴
삭제 : intMap.remove({삭제할 Key값})
연습
자료구조 요리 레시피 메모장 만들기
입력값
저장할 자료구조명을 입력합니다. (List / Set / Map)
내가 좋아하는 요리 제목을 먼저 입력합니다.
이어서 내가 좋아하는 요리 레시피를 한 문장씩 입력합니다.
입력을 마쳤으면 마지막에 “끝” 문자를 입력합니다.
출력값
입력이 종료되면 저장한 자료구조 이름과 요리 제목을 괄호로 감싸서 먼저 출력해줍니다.
이어서, 입력한 모든 문장 앞에 번호를 붙여서 입력 순서에 맞게 모두 출력해줍니다.
내가 작성한 코드 일부
switch (type) {
case "List" :
boolean flag = true;
ArrayList<String> recipeArr = new ArrayList<>();
while (flag) {
String recipe = sc.nextLine();
recipeArr.add(recipe);
if(recipe.equals("끝")) {
flag = false;
}
}
System.out.println("[ " + type + "으로 저장된 " + title + " ]");
for(String item : recipeArr) {
System.out.println(item);
}
break;
정답 코드 일부
switch (collectionName) {
case "List":
ArrayList<String> strList = new ArrayList<>();
while (true) {
// 한줄씩 입력받아서 strList 에 저장
String text = sc.next();
if (Objects.equals(text, "끝")) {
break;
}
strList.add(text);
}
title = "[ List로 저장된 " + title + " ]"; // [ 제목 ]
System.out.println(title);
// strList 한줄씩 출력
for (int i = 0; i < strList.size(); i++) {
int number = i + 1;
System.out.println(number + ". " + strList.get(i));
}
break;
알게 된 점
"끝"을 입력받았을 때 boolean 변수를 false로 바꿔서 while문을 빠져나왔는데 정답코드를 보니 그냥 간단하게 break를 쓰면 됐었다. 아직 break가 익숙지 않아서 이런 차이가 생긴 것 같다.
처음에 레시피를 next()로 받았더니 레시피를 한 줄 단위가 아닌 단어로 받아와서 nextLine()으로 수정했다. 공백을 포함한 한 줄을 온전히 받으려면 nextLine 메서드를 써야겠다.
Java 코드(.java 파일)를 운영체제가 읽을 수 있는 바이트 코드(.class 파일)로 변환
인터프리터
운영체제가 읽은 바이트 코드를 기계어로 번역
JIT 컴파일러
인터프리터의 효율을 높여주는 서포터 해석기
클래스 로더
JVM으로 바이트 코드를 불러와서 메모리에 저장
가비지 컬렉터
메모리 영역에서 안쓰는 데이터를 주기적으로 흡수해가는 청소기
JRE의 기능
Java Runtime Environment 자바 실행 환경
.class 파일만 실행 가능
JDK의 기능
JRE(JVM)의 기능 : .class 파일 실행
Java Compiler(javac) 기능 : .java 파일을 .class 파일로 컴파일
JDB 기능 : 디버깅
기본형 변수
모두 소문자로 시작된다
비객체 타입이므로 null 값을 가질 수 없다. (기본값이 정해져 있음)
변수의 선언과 동시에 메모리 생성
모든 값 타입은 메모리의 스택(stack)에 저장
저장공간에 실제 자료 값을 가진다.
참조형 변수
기본형 과는 달리 실제 값이 저장되지 않고, 자료가 저장된 공간의 주소를 저장한다.
즉, 실제 값은 다른 곳에 있으며 값이 있는 주소를 가지고 있어서 나중에 그 주소를 참조해서 값을 가져온다.
메모리의 힙(heap)에 실제 값을 저장하고, 그 참조값(주소값)을 갖는 변수는 스택에 저장
참조형 변수는 null로 초기화 시킬 수 있다.
String, 객체, 배열, 리스트 등등
Stack 영역 vs Heap 영역
Stack의 경우에는 정적으로 할당된 메모리 영역
크기가 정해져 있는 변수를 저장
크기가 정해져 있는 참조형 변수의 주소 값도 저장
Heap의 경우에는 동적으로 할당된 메모리 영역
크기가 계속 늘어날 수 있는 참조형 변수의 원본을 저장
ASCII 코드 형변환
입력한 정수를 문자로 바꿔서 출력하는 메서드
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int asciiNumber = sc.nextInt();
char ch = (char)asciiNumber;
System.out.println(ch); // 입력한 글자를 출력합니다.
}
}
입력한 문자의 제일 첫 글자를 숫자로 출력하는 메서드
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int letter = sc.nextLine().charAt(0); // charAt(0) :첫번쨰 문자를 받아온다.
int asciiNumber = (int)letter;
System.out.println(asciiNumber); // 입력한 글자를 출력합니다.
}
}