Today's Codekata
class Solution {
public String solution(String[] seoul) {
int x = 0;
while (!seoul[x].equals("Kim")) {
x++;
}
return "김서방은 " + x + "에 있다";
}
}
있다 뒤에 . 을 넣어준 것이 오답의 원인이었다. 작은 디테일 하나 놓치지 않는 눈이 개발자에게 중요해보인다.
import java.util.Arrays;
class Solution {
public int[] solution(int[] arr, int divisor) {
int count = 0;
for (int num : arr) {
if (num % divisor == 0) {
count++;
}
}
if (count == 0) {
return new int[] {-1};
}
int[] answer = new int[count];
int i = 0;
for (int num : arr) {
if (num % divisor == 0) {
answer[i++] = num;
}
}
Arrays.sort(answer);
return answer;
}
}
int[] answer = Arrays.stream(arr).filter(factor -> factor % divisor == 0).toArray();
배열에 대한 공부가 부족하다고 생각해서 찾아가며 익숙한 컬렉션을 사용하지 않으면서 답에 도달하려고 했다. 자바 배열은 고정 크기이기 때문에, 요소 개수를 먼저 세고 그 크기에 맞춰 새 배열을 만들어야 한다는 점을 이해할 수 있었다. 아래에 다른 사람의 풀이를 통해 스트림을 활용해서 아주 간결하게 answer에 담아내는 방식도 배울 수 있었다.
SELECT WAREHOUSE_ID, WAREHOUSE_NAME, ADDRESS,
CASE WHEN FREEZER_YN IS NULL THEN 'N'
ELSE FREEZER_YN END AS FREEZER_YN
FROM FOOD_WAREHOUSE
WHERE ADDRESS LIKE '경기도%'
ORDER BY WAREHOUSE_ID;
SELECT FACTORY_ID, FACTORY_NAME, ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '강원도%'
ORDER BY FACTORY_ID;
SQL의 기본 문법에 대한 이해도가 조금씩 높아져 가고 있다.
키오스크 프로젝트
AtomicInteger menuNumber = new AtomicInteger(1);
menu.stream()
.map(Menu::getCategory)
.filter(category -> menuNumber.get() <= 3) // .limit(3)을 사용하는게 더 좋아보인다.
.forEach(category -> System.out.println(menuNumber.getAndIncrement() + ". " + category));
오늘은 AtomicInteger를 활용해서 메뉴 카테고리를 꺼내와 출력하는 Stream으로 본 것을 IntStream을 활용해 수정해보려한다.
IntStream
Stream API의 정수형 전용 버전이라 할 수 있다. 기본형 int 값을 다룰 때 성능과 간결함을 동시에 챙길 수 있다.
주요 생성 방법
| 메서드 | 설명 |
| IntStream.of(1, 2, 3) | 직접 값을 지정 |
| IntStream.range(1, 5) | 1부터 4까지 (마지막 값 포함 X) |
| IntStream.rangeClosed(1, 5) | 1부터 5까지 (마지막 값 포함 O) |
| IntStream.generate(() → 1) | 무한 스트림 생성 |
| IntStream.iterate(1, i → i + 1) | 시드값부터 함수로 반복 |
IntStream.range(0, 3) // 0 ~ 2까지 들어있는 int[] 생성
.forEach(num -> System.out.println((num + 1) + ". " +menu.get(num).getCategory()));
IntStream.rangeClosed(0, items.size())
.forEach(index -> System.out.println((index + 1) + ". " + formatMenu(items.get(index))));
AtomicInteger를 활용했던 코드를 IntStream을 활용해서 리팩토링했다. 상단 코드는 정상적으로 작동하는데, 하단 코드는 버그가 발생했다. IndexOutOfBoundsException 예외가 뜬 것인데, 내가 범위를 벗어난 인덱스를 조회한 듯하다. rangeClosed를 사용해서 0부터, items.size()까지 BURGER MENU에 아이템이 4개가 들어있다면 0, 1, 2, 3 이렇게 가져올거라 생각했는데, 무엇이 잘못됐을까... 해당 코드에 breakpoint를 설정하고 살펴보니 계속 index : 4 가 들어가길래 뭐가 잘못됐을까 했는데, .range()를 써야할 것을 햇갈려서 .rangeClosed()를 사용한 것이었다. 그 부분을 수정해주니 정상적으로 작동되는 것을 확인했다.
if (finalChoice == 3) {
System.out.println(" [ ORDERS ] ");
IntStream.range(0, cartItems.size())
.forEach(index -> System.out.println((index + 1) + ". " + formatMenu(cartItems.get(index))));
System.out.println("\n주문에서 제외할 메뉴의 번호를 입력해주세요.");
int cancelMenu = sc.nextInt();
if (cancelMenu >= 1 && cancelMenu <= cartItems.size()) {
System.out.println(cartItems.get(cancelMenu - 1).getName() + " 가 삭제되었습니다.");
cartItems.remove(cancelMenu - 1);
} else {
throw new IllegalArgumentException("잘못된 번호를 입력하셨습니다.");
}
if (cartItems.isEmpty()) {
System.out.println("장바구니가 비어있습니다. 메인 화면으로 돌아갑니다.");
order = false;
}
}
추가로 주문 확인 창에서 제외하고 싶은 메뉴를 선택하고 해당 항목을 삭제하는 기능을 추가했다.
/**
* 콘솔 기반의 키오스크 시스템입니다.
* 메뉴 목록을 출력하고, 메뉴 선택 및 주문 기능을 제공합니다.
*/
public class Kiosk {
private final List<Menu> menu;
private final Scanner sc = new Scanner(System.in);
// 사용자가 선택한 메뉴를 담는 장바구니 List
private final List<MenuItem> cartItems = new ArrayList<>();
public Kiosk(List<Menu> menu) {
this.menu = menu;
}
// 키오스크의 메인 메뉴를 출력하고 사용자 선택에 응답합니다.
public void start() {
while (true) {
....
코드들에 주석을 달고 전체적으로 살펴보고 있다. 이제 기능 구현은 어느 정도 마무리 되었지만 각 클래스와 구현된 메서드들이 그 역할과 책임이 분명한지 고민이 된다. menuItem들을 main()메서드에서 추가해줄 필요가 있는지 현재 enum 안에서 계산까지 되고 있는게 타당한지 이런저런 생각들이 든다. 불필요한 책임이 한 곳에 몰리지 않도록 나누는 과정은 어렵지만 반드시 필요한 성장의 과정이라 생각된다.
마치며
이 키오스크는 가이드에 따라 만든 것이긴 하지만, 내가 구현했기 때문에 전적으로 내가 생각하는 방향으로 구조와 흐름이 설계되어있다. 이 부분이 아주 중요하다는 생각이 든다. 어떤 클래스를 만들 것인지, 그 안에 어떤 기능을 담을 것인지, 이 키오스크가 어떤 동작들을 수행하게 할 것인지 모두 내 생각과 가치관들이 내가 입력한 코드에 드러날 것이다. 개발자는 주어진 기능만을 구현하는 사람이 아니라, 어떤 경험과 목적을 기술로 풀어내는 사람이라 생각된다. 앞으로 만들어갈 모든 프로젝트들도 그 쓸모와 완성도는 결국 나에게 달려있다. 무엇을 만들지보다 어떻게 만들지, 그리고 왜 그렇게 만들었는지를 얘기할 수 있는 개발자가 되도록 해야겠다.