코트카타
28) 없는 숫자 더하기
나의 풀이
import java.util.*;
class Solution {
public int solution(int[] numbers) {
int answer = -1;
Set<Integer> allNumbers = new HashSet<>();
for (int i = 0; i <= 9; i++) {
allNumbers.add(i);
}
for (int num : numbers) {
allNumbers.remove(num);
}
answer = allNumbers.stream().mapToInt(Integer::intValue).sum();
return answer;
}
}
0~9까지의 값이 있는 Set을 생성해서
기존 numbers 배열에 있는 값을 제거했다.
그리고 스트림을 이용해서 Set의 값을 더했다.
.mapToInt(Integer::intValue)
- Stream<Integer>를 IntStream으로 변환
- Stream<Integer>는 일반 객체 Stream이지만, IntStream은 기본형 int 값을 위한 스트림으로 더 효율적으로 처리가능
- 각 Integer 객체를 기본형 int로 변환하는 역할
- 효율적인 연산: sum(), average() 같은 기본형에 최적화된 연산이 가능
다른 분들의 풀이
class Solution {
public int solution(int[] numbers) {
int sum = 45;
for (int i : numbers) {
sum -= i;
}
return sum;
}
}
출처:https://school.programmers.co.kr/learn/courses/30/lessons/86051/solution_groups?language=java
합을 구하는 문제였기 때문에 위와 같은 방법으로 하는 것이 더 깔끔해 보인다.
개인 과제 진행
Lv6-1 트러블슈팅
MVC 패턴 적용 : KioskView와 KioskController 분리
어제 튜터님께서
View에는 입출력(Scanner),
Controller에는 각 조건에 맞게 처리하는 로직
이렇게 구현하라고 말씀해주셨다.
1) KioskController에서 사용하는 Scanner 처리방법
- Scanner에서 숫자를 입력 받아서 처리하는 로직
int chooseCart = sc.nextInt();
- if 문 안에서 예외처리로 sc.nextLine(); 사용 로직
if (chooseMainMenu < 0 || chooseMainMenu > 5) {
System.out.println("보기 중에 없는 번호입니다. 다시 입력해주세요.");
sc.nextLine();
}
위 2문제를 아래와 같이 해결했다.
KioskView kiosk = new KioskView();
KioskController에서 KioskView 객체를 생성한다.
int chooseCart = kiosk.chooseNumber();
KioskView 클래스의 메서드 반환값을 KioskController 변수에 넣는다.
// Scanner 선언
Scanner sc = new Scanner(System.in);
public int chooseNumber() {
return sc.nextInt();
}
public void nextLine(){
sc.nextLine();
}
KioskView 클래스에 메서드로 분리하여 사용하는 것이다.
2. NullPointerException 예외 처리
메인 메뉴는 3가지이지만, 메뉴 아이템(상세메뉴)은 햄버거 밖에 없다.
따라서 나머지 음료와 디저트 메인 메뉴를 선택할 경우, NullPointerException이 발생한다.
팀원분께서 NullPointerException은
try-catch문으로 예외처리하는 것보다는
사전에 해당 오류가 발생하지 않도록 처리하는 것이 더 좋다고 하셨다.
따라서 catch문 -> if 문 안으로 넣어서 처리했다.
if (menuItems != null){
System.out.println("해당 메인 메뉴의 상세 메뉴가 없습니다.");
continue;
}
튜터님께서 ObjectUtils.isEmpty()를 추천해주셨다.
empty인지 확인하는 메서드인데
좋은 점은 Null 과 size가 0인지 같이 확인하는 점이 장점이다.
그런데 ObjectUtils 클래스를 사용하려고 하는데, 자동으로 import가 되지 않는다.
찾아보니 의존성 주입을 해야 한다고 한다.
그래서 build.gradle에 들어가서 아래와 같이 추가해주었다.
dependencies {
implementation 'org.apache.commons:commons-lang3:3.12.0'
}
if (ObjectUtils.isEmpty(menuItems)){
System.out.println("해당 메인 메뉴의 상세 메뉴가 없습니다.");
continue;
}
이렇게 추가해주면 위의 조건문이 잘 실행된다.
Lv6-2 트러블슈팅
Enum을 활용해 사용자 유형에 맞게 할인율 적용
팀원분께서 할인율도 같이 Enum 값에 넣으면 좋겠다고 제안해주셨다.
public enum User {
VETERAN(1,10),
SOILDER(2,5),
STUDENT(3,3),
GENERAL(4,0);
//값을 저장할 필드(인스턴스 변수)
private final int value; //순서
private final double discountRate; //할인율
}
위와 같이 각 Enum에 value와 할인율을 각각 저장해주었다.
// userDiscount : 사용자의 할인율에 따라 총 합계를 계산해서 출력하는 함수
public double userDiscount(Cart cart, int chooseUser) {
User user = User.findByVal(chooseUser);
double totalPrice = cart.totalPriceCal();
switch (user) {
case VETERAN:
totalPrice -= totalPrice * (User.VETERAN.getDiscountRate() / 100);
break;
case SOILDER:
totalPrice -= totalPrice * (User.SOILDER.getDiscountRate() / 100);
break;
case STUDENT:
totalPrice -= totalPrice * (User.STUDENT.getDiscountRate()/ 100);
break;
case GENERAL:
totalPrice -= totalPrice * (User.GENERAL.getDiscountRate()/ 100);
break;
default:
throw new IllegalStateException("잘못된 번호입니다.");
}
System.out.printf("주문이 완료되었습니다. 금액은 W %.2f 입니다.%n", totalPrice);
return totalPrice;
}
이렇게 하면 기존에 총합계 계산식에
10%, 5%, 3%, 0%와 같은 숫자를 곱하는 것이 아니라
각각에 해당하는 Enum의 할인율을 가져와서 사용하니까 더 직관적이다.
// enum의 값이 매개변수와 같으면 enum의 값을 리턴합니다.
public static User findByVal(int value) {
User[] values = User.values();
for (User v : values) {
if (value ==v.value) {
return v;
}
}
throw new IllegalStateException("잘못된 번호입니다.");
}
또한 기존에 return null;을 처리해서 생기는 NullPointerException은
예외처리를 throw로 처리해주었다.
람다 & 스트림을 이용해 장바구니 목록 삭제하기 기능 구현
나의 경우에는 5번 Cancel을 선택하면
장바구니 목록 중 선택한 번호의 메뉴 아이템이 삭제되도록 구현하고자 했다.
[ ORDER MENU ]
4. Orders
5. Cancel
5
장바구니 목록
1. Hamburger | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
2. ShackBurger | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거
삭제할 메뉴 아이템을 선택하세요.
2
ShackBurger 해당 메뉴가 장바구니에서 삭제되었습니다.
장바구니 목록
1. Hamburger | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
먼저 내가 구현하고 싶은 코드를 람다, 스트림을 사용하지 않고 작성해보았다.
그러다가 아래와 같은 예외가 발생했다.
Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967) at com.example.kiosk.level6.model.Cart.removeMenuItem(Cart.java:33) at com.example.kiosk.level6.Controller.KioskController.start(KioskController.java:68) at com.example.kiosk.level6.Main.main(Main.java:30)
출처 : https://jyyoun1022.tistory.com/12
순회중에 값을 제거했기 때문에
맨 마지막 목록의 값을 제거하면 위와 같은 Exception이 나오게 된다.
배열이나 리스트에 자주 사용하는 for each문 -> for문으로 수정해서 구현했다.
//stream 활용 전 코드 작성 - 주석처리
for (int i = 0 ;i<cartList.size();i++) {
MenuItem cartItem = cartList.get(i);
if(cartList.indexOf(cartItem)+1 == chooseMenuItemNumber){
cartList.remove(cartList.indexOf(cartItem));
System.out.println(cartItem.getName()+" 해당 메뉴가 장바구니에서 삭제되었습니다.\n");
}
}
위의 내용을 람다와 스트림을 활용해서 작성하기
cartList.stream()
.filter(cartItem -> cartList.indexOf(cartItem) + 1 == chooseMenuItemNumber)
.findFirst()
.ifPresent(cartItem -> {
cartList.remove(cartItem);
System.out.println(cartItem.getName() + " 해당 메뉴가 장바구니에서 삭제되었습니다.\n");
});
.filter(cartItem -> cartList.indexOf(cartItem) + 1 == chooseMenuItemNumber):
- 스트림의 각 요소(cartItem)에 대해 필터링을 수행
- cartList.indexOf(cartItem) : 현재 cartItem의 인덱스를 반환
- 여기에 1을 더해 선택한 메뉴 번호와 일치시킴(인덱스는 0부터 시작하므로).
- 위의 값이 사용자가 선택한 메뉴 번호(chooseMenuItemNumber)와 일치하는지 확인
- 조건이 참인 요소만 다음 단계로 전달
.findFirst():
- 필터링된 결과 중 첫 번째 요소를 선택
- Optional 객체를 반환
(값이 존재할 수도, 존재하지 않을 수도 있음을 나타냄)
.ifPresent(cartItem -> { ... }):
- Optional 객체에 값이 존재하는 경우에만 내부의 람다 표현식을 실행
- 값이 없으면(해당 번호의 메뉴가 없으면) 아무 동작도 하지 않음
람다...스트림...
익숙하지 않아 다양한 예제를 접하면서 익혀야 할 것 같다.
그래도 두 번째 개인 과제라서 그런지
첫 번째 과제보다 더 짧은 시간이 주어졌는데도 불구하고,
여기까지 잘 올 수 있게 된 것 같아 기쁘다. :)
'CODING > 스파르타 내일배움캠프 TIL' 카테고리의 다른 글
28_가운데 글자 가져오기_Spring 입문_25.1.21(화) (0) | 2025.01.21 |
---|---|
27_제일 작은 수 제거하기_키오스크 과제 해설_스탠다드 백엔드 개발자 필수 지식_25.1.20(월) (0) | 2025.01.20 |
키오스크 개인과제 관련 트러블슈팅 TIL 모음 (0) | 2025.01.17 |
25_핸드폰 번호 가리기_도전과제 레벨 6-1 구현_자바 강의 String_25.1.16(목) (1) | 2025.01.16 |
24_음양 더하기_자바 강의 다형성, Object_25.1.15(수) (0) | 2025.01.15 |