미션3 구현하기
사용자 정의 예외 다시 추가
어제 코드리뷰를 받고 Question 객체를 DAO에서 꺼내올때 orElseThrow를 사용하는 부분에서 NoSuchElementException은 여기에 맞지 않는다는 피드백을 받았다. NoSuchElementException은 배열이나 리스트에 요소가 없을때 쓰이는 것이라 함
NotFoundException이 더 적절한거같다고해서 변경하려고하니 checked예외이기때문에 메소드를 호출하는 다른 메소드들까지도 예외처리를 해야되고 코드가 복잡해져서 사용자 정의예외로 unchecked 예외로 새로 만들었다.
@ControllerAdvice
모든 controller에서 발생할수 있는 예외를 처리해주는 어노테이션
@ControllerAdvice, @ExceptionHandler를 이용한 예외처리 분리, 통합하기(Spring에서 예외 관리하는 방법, 실무에서는 어떻게?)
@RestController는 @ControllerAdvice와 같은 역할을 하고 추가적인 기능(@ResponseBody를 통해 객체를 리턴할수 있음)을 수행한다고 하는데 이 기능이 아직까진 필요하진 않은듯하다.
LocalDateTime 포맷팅하기
public String getPostTime() {
return postTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
}
format()메소드를 이용해서 인자로 DateTimeFormatter를 넣어줘야함
@Transactional
[Spring] Transactional 정리 및 예제
로치가 어제 간략화해서 쉽게 설명해주시고 틀린부분이 있을수 있으니 참고하라고 보내준 블로그인데 아직 어려운내용인거 같다. cs10때 학습한 트랜잭션에 대한 내용만 한번 더 훑어봤다.
Foreign Key(외래키)
두 테이블을 서로 연결하는데 사용되는 키
외래키가 포함된 테이블이 자식테이블이고 외래키 값을 제공하는 테이블이 부모 테이블
이코테 알고리즘 정렬파트
선택정렬(157p)
가장 작은 데이터를 앞으로 보내는 정렬
시간복잡도 O()
다른 알고리즘에 비해 비효율적이지만 가장 작은 데이터를 찾는 일이 있어서 선택정렬을 알아야함
public static void main(String[] args) {
int n = 10;
int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8};
for (int i = 0; i < n; i++) {
int min_index = i;
// 가장 작은 원소 찾기
for (int j = i + 1; j < n; j++) {
if (arr[min_index] > arr[j]) {
min_index = j;
}
}
// 스와프
int temp = arr[i];
arr[i] = arr[min_index];
arr[min_index] = temp;
}
for (int i : arr) {
System.out.print(arr[i] + " ");
}
}
삽입정렬
시간복잡도 O()인데 정렬이 거의 되어있는 상태에서는 퀵정렬보다 시간복잡도가 낮다.
public static void main(String[] args) {
int n = 10;
int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8};
// 인텍스 1부터 시작, 첫번째 데이터 기준으로 자리바꿈
for (int i = 1; i < n; i++) {
for (int j = i; j > 0; j--) {
// 스와프
if (arr[j] < arr[j - 1]) {
int tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
} else break;
}
}
for (int i : arr) {
System.out.print(i + " ");
}
}
퀵정렬
정렬알고리즘 중 가장 많이 사용됨
피벗 : 교환하기 위한 기준
다른 정렬알고리즘과 다르게 정렬되어있는 상태에서는 매우 느리게 동작한다.
O()
→ 퀵정렬 코드는 이해가 안감
계수정렬
O(N+K)
K: 데이터 중 최대값의 크기
동일한 데이터가 여러개 등장할때 적합하다.
실전문제
178p 라이브러리쓰는건 역시 쉽군
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Integer[] arr = new Integer[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
Arrays.sort(arr, Collections.reverseOrder());
for (int i : arr) {
System.out.print(i + " ");
}
}
180p
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
Map<Integer, String> students = new HashMap<>();
for (int i = 0; i < n; i++) {
String[] line = sc.nextLine().split(" ");
students.put(Integer.parseInt(line[1]), line[0]);
}
Object[] keyArr = students.keySet().toArray();
Arrays.sort(keyArr);
// 정렬된 키 순서대로 get(key)로 value인 학생 출력
for (Object key : keyArr) {
System.out.print(students.get(key) + " ");
}
}
map으로 값을 넣고, key를 정렬하여 value인 학생을 출력하게 했다.
TreeMap은 자동 정렬이 되니깐 TreeMap을 사용하는게 더 낫겠다.
182p
n크기의 두 배열을 입력받고, k번의 횟수만큼 두 배열의 요소를 바꿔서 배열a 요소의 합이 최대가 되도록 하기
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
sc.nextLine();
Integer[] aArr = new Integer[n];
Integer[] bArr = new Integer[n];
for (int i = 0; i < n; i++) {
aArr[i] = sc.nextInt();
}
sc.nextLine();
for (int i = 0; i < n; i++) {
bArr[i] = sc.nextInt();
}
Arrays.sort(aArr);
Arrays.sort(bArr, Collections.reverseOrder());
for (int i = 0; i < k; i++) {
aArr[i] = bArr[i];
}
int result = 0;
for (Integer i : aArr) {
result += i;
}
System.out.println(result);
}
배열 a의 제일 작은 원소와 배열 b의 제일 큰 원소끼리 바꾸기
aArr는 오름차순 정렬, bArr는 내림차순 정렬해서 바꿔치기