📖 쪽집게 과외
✅ 이것만은 꼭 정리해놓자!
for
for (int i = 0; i < 10; i++) {
System.out.println("i);
}
while
int i = 0;
while (i < 10) {
System.out.println(i);
i++;
}
break
for (int i = 0; i < 10; i++) {
System.out.println(i);
if (i == 5) {
break;
}
}
📖 연습 문제) 구구단 프로그램
import java.util.Scanner;
public class Gugudan {
public int helper() {
System.out.println("[구구단] 몇 단을 출력하실건가요?");
Scanner scan = new Scanner(System.in);
String str = scan.nextLine();
int res = this.exit(str);
if (res == 0)
return 0;
else if (res == 1)
return this.helper();
else if (res == 2)
this.gugudan(Integer.parseInt(str));
return this.helper();
}
public int exit(String str) {
int num= 0;
int res = 1;
if (str.equals("exit")) {
System.out.println("프로그램을 성공적으로 종료했습니다.");
return res = 0;
}
try {
num = Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("1 ~ 9사이의 숫자만 입력 가능합니다.");
return res = 1;
}
if ( 1 > num || num > 9) {
System.out.println("1단에서 9단까지만 출력이 가능합니다.");
return res = 1;
}
if (1 <= num && num <= 9) {
res = 2;
}
return res;
}
public void gugudan(int dan) {
for (int i = 1; i < 10; i++) {
System.out.println(dan + " * " + i + " = " + dan*i);
}
}
public static void main(String[] args) {
Gugudan g = new Gugudan();
g.helper();
}
}
✅ 이것만은 꼭 정리해놓자!
import java.util.ArrayList;
import java.util.Collections;
public class ArrayListExample {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
// Inserting data into the ArrayList using add()
numbers.add(1);
numbers.add(2);
numbers.add(3);
// Retrieving specific data from the ArrayList using get()
int secondNumber = numbers.get(1);
System.out.println("The second number is: " + secondNumber);
// Removing specific data from the ArrayList using remove()
numbers.remove(1);
// Retrieving all data from the ArrayList using get()
System.out.println("The numbers in the ArrayList are: ");
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
// Retrieving the index of a specific value in the ArrayList using indexOf()
int indexOfThree = numbers.indexOf(3);
System.out.println("The index of 3 is: " + indexOfThree);
// Sorting the data in the ArrayList using Collections.sort()
Collections.sort(numbers);
System.out.println("The numbers in the ArrayList sorted in ascending order are: ");
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
// Checking if a specific value exists in the ArrayList using contains()
boolean containsOne = numbers.contains(1);
System.out.println("The ArrayList contains 1: " + containsOne);
// Retrieving the total number of elements in the ArrayList using size()
int sizeOfArrayList = numbers.size();
System.out.println("The size of the ArrayList is: " + sizeOfArrayList);
}
}
📖 연습 문제) ArrayList와 친해지기
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ArrayListExample {
public static void main(String[] args) {
// 정수(int) 데이터를 담을 빈 ArrayList를 만들어라.
ArrayList<Integer> array = new ArrayList<>();
// `ArrayList`에 `5`, `7`, `10`, `9`, `4`라는 데이터를 차례대로 넣어라.
array.add(5);
array.add(7);
array.add(10);
array.add(9);
array.add(4);
// ArrayList에서 7이라는 데이터를 삭제해라.
int valueToRemove = 7;
array.removeIf(num -> num == valueToRemove);
// ArrayList에 들어있는 두 번째 값을 조회해서 출력해라.
System.out.println(array.get(1)); //10
// ArrayList를 내림차순으로 정렬해라.
Collections.sort(array, Comparator.reverseOrder());
// for문을 활용해서 ArrayList의 모든 데이터를 차례차례 출력해라.
for (int i = 0; i < array.size(); i++) {
System.out.println(array.get(i));
}
// ArrayList안에 11의 값이 존재하는 지 여부를 출력해라.
System.out.println(array.contains(11));
}
}
🎯 학생들의 이름을 가나다 순으로 출력하기
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ThirdMission {
public static void main (String[] args) {
System.out.println("학생의 이름을 입력하고 엔터를 누르세요. (한글로만 입력해야 합니다.)");
System.out.println("학생들을 다 입력했다면, print라고 입력해주세요.");
ArrayList<String> array = new ArrayList<>();
Scanner scan = new Scanner(System.in);
boolean bool = true;
while (bool) {
String str = scan.nextLine();
if (str.equals("print"))
break;
Pattern pattern = Pattern.compile("[^ㄱ-ㅎ가-힣]");
Matcher matcher = pattern.matcher(str);
if (matcher.find())
System.out.println("학생의 이름은 한글로만 입력해야 합니다.");
else
array.add(str);
}
System.out.println("[학생 명단(가나다순)]");
Collections.sort(array);
for(int i = 0; i < array.size(); i++) {
System.out.println(array.get(i));
}
}
}
🎯 100m 달리기 선수 중 1등 찾기
import java.util.ArrayList;
import java.util.Scanner;
public class findNumberOne {
private static final int RES_INVALID = -1;
private static final int RES_PERSON_NUMBER = 1;
private static final int RES_RACE_RECORD = 2;
private static final int MIN_PERSON_NUMBER = 0;
private static final int MAX_PERSON_NUMBER = 100;
public int checkType(String num) {
try {
int integerOnly = Integer.parseInt(num);
if (integerOnly < MIN_PERSON_NUMBER) {
Double.parseDouble(num);
}
return RES_PERSON_NUMBER;
} catch (NumberFormatException e) {
try {
Double.parseDouble(num);
return RES_RACE_RECORD;
} catch (NumberFormatException f) {
System.out.println("선수 번호 입력시에는 자연수, 100m 달리기 기록에는 자연수 및 실수를 입력해주세요\n");
}
}
return RES_INVALID;
}
public int inputPersonNumber(findNumberOne obj) {
System.out.println("선수의 번호를 입력하세요.");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
if (input.equals("print")) {
return Integer.MIN_VALUE;
}
int result = obj.checkType(input);
if (result == RES_PERSON_NUMBER && Integer.parseInt(input) > 100) {
System.out.println("100 미만의 번호만 입력해주세요.\n");
return inputPersonNumber(obj);
}
if (result == RES_PERSON_NUMBER && Integer.parseInt(input) < 0) {
System.out.println("자연수만 입력해주세요.\n");
return inputPersonNumber(obj);
}
if (result == RES_INVALID || result == RES_RACE_RECORD) {
return inputPersonNumber(obj);
}
return Integer.parseInt(input);
}
public double inputRaceRecord(findNumberOne obj) {
System.out.println("이 선수의 100m 달리기 기록이 몇 초인지 입력하세요.");
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
if (input.equals("print")) {
return Integer.MIN_VALUE;
}
int result = obj.checkType(input);
if (result == RES_INVALID) {
return inputRaceRecord(obj);
}
return Double.parseDouble(input);
}
public static void main(String[] args) {
ArrayList<Double> records = new ArrayList<>(MAX_PERSON_NUMBER);
findNumberOne obj = new findNumberOne();
boolean check = false;
for (int i = 0; i < 100; i++) {
records.add(null);
}
while (true) {
int personNumber = obj.inputPersonNumber(obj);
if (personNumber == Integer.MIN_VALUE) {
check = true;
break;
}
double raceRecord = obj.inputRaceRecord(obj);
if (raceRecord == Integer.MIN_VALUE) {
check = true;
break;
}
records.set(personNumber, raceRecord);
}
if (check) {
double min = Double.MAX_VALUE;
int index = Integer.MIN_VALUE;
int totalPeople = 0;
for (Double elem : records) {
if (elem == null) {
continue;
}
totalPeople += 1;
if (min >= elem) {
index = records.indexOf(elem);
min = elem;
}
}
if (min == Double.MAX_VALUE) {
return;
}
System.out.printf("1등 : %d번 선수 / %.2f초 (참가인원 : %d명)", index, min, totalPeople);
} else {
System.out.println("No values to calculate.");
}
}
}
*1등과 2등의 기록이 같은 경우 1등 출력
3회차 심화미션
✅ JCF에 대해 설명해주세요
Java에서 인터페이스와 자료구조들을 미리 구현해 놓은 패키지이다. JCF는 Java Collection Framework로 불리는데 Framework가 넓은 의미로 쓰이면 앱을 개발하는데 제공되는 패키지이다. 따라서 Spring, Django, Laravel과 같은 의미의 Framework로 사용되는 것은 아니다. 해당 패키지 안에는 클래스와 인터페이스가 있다. 화살표를 잘 보면 인터페이스가 인터페이스를 상속 받은 것과 인터페이스를 상속받은 클래스를 확인 할 수 있다.
참고
JCF를 사용하는 이유
1) 손으로 필요한 클래스를 구현한 것보다 최적화와 성능면에서 우수하다.
2) 개발자들이 같은 패키지를 사용함으로써 코드에 일관성이 생긴다.
3) 검증된 패키지이기 때문에 필요한 로직을 작성하는데 집중할 수 있다.
4) 비즈니스 로직을 작성하는데 집중하므로 생산성이 향상된다.
✅ 제네릭(Generic)에 대해 설명해주세요
자바에서 클래스 인터페이스 그리고 메서드를 사용할 때 파라미터로 타입을 지정함으로써 사용자로 하여금 클래스 인터페이스 메서드를 재사용 할 수 있게 하고 타입 세이프한 코드를 작성할 수 있도록 돕는 역할을 수행한다. 해당 회차에서 배운 ArrayList를 사용할 때 타입을 지정함으로써 가변 배열에 저장하고자 하는 타입의 원소를 사용자가 정할 수 있게 함으로써 ArrayList라는 클래스를 여러 타입으로 재 사용 할 수 있게 하고 지정한 타입의 데이터만 매니징 할 수 있게 함으로써 타입 safe를 보장한다.
✅ String, StringBuilder, StringBuffer 각각의 차이에 대해 설명해주세요
String
String은 불변객체이다. 연속된 character를 표현해준다. 불변 객체라는 것은 값을 변경 할 수 없다는 것을 의미한다. 만약 사용자가 String type의 값이 할당된 변수의 값을 바꾼다면 해당 변수의 값이 변경돼서 바뀐 값이 출력되는 것이 아니라 해당 변수가 Heap memory의 String Pool에 새로 생성된 String 객체를 참조하는 것이다. 따라서 String immutable의 대상은 Heap memory내 String Pool에 생성된 String 객체이다.
언제 사용 하면 좋은가?
String은 불변성을 가지기 때문에 변하지 않는 문자열을 자주 읽어들이는 경우 String을 사용해 주시면 좋은 성능을 기대할 수 있다.
Immutable 객체의 장점
메모리 절약
메모리를 절약할 수 있다. new String() 으로 객체를 생성하지 않고 String variable = "Hello"의 형식으로 변수명을 다르게 하고 여러개의 객체를 생성한 경우 여러개의 변수가 하나의 객체를 참조하기 떄문에 메모리에 대한 이점이 있다. 만약 가변객체에 여러 변수가 동일한 메모리를 참조하게 된다면 하나의 변수의 값만 변경해도 해당 객체를 참조하고 있는 모든 변수의 값에 변경이 일어나는 문제점이 있을 것이다.
Integer.toHexString(System.identityHashCode(str))
위는 str안에 String 타입의 변수가 들어왔을 때 hashCode를 통해 변수가 동일한 객체를 참고하는지 확인 할 수 있다.
쓰레드세이프
수천 수만개의 Thread가 메모리상의 같은 String Object를 참조 한다고 해도, 어느 Thread에서도 값을 변경 할 수 없기 때문에 Thread Safe 가 보장된다.
언제 사용 하면 안되나?
문자열 추가,수정,삭제 등의 연산이 빈번하게 발생하는 알고리즘에 String 클래스를 사용하면 힙 메모리(Heap)에 많은 임시 가비지(Garbage)가 생성되어 힙메모리가 부족으로 어플리케이션 성능에 악영향을 끼친다.
String vs StringBuilder vs StringBuffer
공통점
세 객체 모두 연속된 문자열을 표현한다.
차이점
String 객체와 다르게 StringBuilder와 StringBuffer 값이 변경 가능한 객체이다.
StringBuilder vs StringBuffer
StringBuffer
StringBuffer는 thread-safe 하다. 따라서 변경가능한(mutable) 객체에 대해 여러 thread가 접근해야 할 때 StringBuilder보다 StringBuffer를 사용한다. 여러 Thread 하나의 공유된 자원에 접근 할 경우 동기화를 보장한다.
public class StringBufferExample {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer();
int total = 0;
for (int i = 0; i < 15; i++) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
buffer.append(" Thread 1 ");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
buffer.append(" Thread 2 ");
}
});
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
buffer.append(" Thread 3 ");
}
});
thread1.start();
thread2.start();
thread3.start();
try {
thread1.join();
thread2.join();
thread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(buffer.toString());
total += 1;
buffer.setLength(0);
}
System.out.println(total);
}
}
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
Thread 1 Thread 2 Thread 3
15
StringBuilder
StringBuilder는 thread-safe하지 않다. 그렇지만 동기화를 고려하지 않는 만큼 단일쓰레드에서의 성능은 StringBuffer 보다 뛰어나다.
정리
String : 문자열 연산이 적고 멀티쓰레드 환경일 경우
StringBuffer : 문자열 연산이 많고 멀티쓰레드 환경일 경우
StringBuilder : 문자열 연산이 많고 단일쓰레드이거나 동기화를 고려하지 않아도 되는 경우