2차원 배열 평탄화하기

상우·2025년 4월 11일
post-thumbnail

상황

학교 과제로 영화관 좌석 예매 프로그램을 만들었다.
영화관 좌석을 10X10 2차원 배열로 만들었는데
예약자 명으로 좌석을 찾으려고 할때 문제가 생겼다.

MovieTheater.java

public class MovieTheater {

    private Reservation[][] seats;

    public MovieTheater(int numRows, int numCols) {
        seats = new Reservation[numRows][numCols];
    }

...

    // 예약 정보 조회 메서드
    public void displayReservationInfo (String name){


    }
}

Reservation.java

package week4;

public class Reservation {

    private int row;
    private int col;
    private String customerName;
    private String customerPhoneNumber;

    public Reservation(int row, int col, String customerName, String customerPhoneNumber) {
        this.row = row;
        this.col = col;
        this.customerName = customerName;
        this.customerPhoneNumber = customerPhoneNumber;
    }

    public char getRow() {
        return (char) row;
    }

    public int getCol() {
        return col;
    }

    public String getCustomerName() {
        return customerName;
    }

    public String getCustomerPhoneNumber() {
        return customerPhoneNumber;
    }
}

예약자명으로 예약정보를 찾는 기능을 만드려고 했고
이를 구현하기 위해선

Reservation 객체를 관리하고 있는 2차원 배열에서
특정 customerName을 가진 Reservation 객체를 찾아낼 수 있어야했다

스트림을 사용하면 편리하겠다 싶어서
스트림으로 filter를 걸어,
특정 customerName인 Reservation을 찾아 내려고했다

문제

문제는 Reservation 2차원 배열을 스트림으로 바꿨을 때
filter를 사용해서 나오는 요소는
Reservation이 아니고
Reservation[] 이라는 것이었다.

2차원 배열은 배열안에 배열이 있는 형태이기 때문에
2차원 배열의 각 요소는 1차원 배열이 되고
2차원 배열을 스트림으로 바꾸었을때에도
2차원 배열 스트림이 반환하는 요소는 1차원 배열이었다.

즉 2차원 배열의 스트림에서 filter를걸어 customerName으로 특정 Reservation 객체를 찾는것이 불가능하게 되었다.

해결

방법이 있을것 같아서 stream으로 2차원 배열을 다루는 방법에 대해 찾아보던중
flatmap()이라는 메서드를 발견하게 되었다.

2차원 형태를 1차원 형태로 변환시켜주는 메서드였다.

2차원 배열형태로 관리되던 Reservation 객체를
전부 1차원배열로 형태를 변환해서 관리한다면
위의 고민이 해결된다

1차원 배열을 스트림으로 변환해서
필터를 걸어주면
Reservation 객체를 반환할것이기 때문

즉 다차원 스트림의 요소를 관리하기 편하도록
1차원 스트림으로 평탄화해주는 메서드가 flatmap이었다.

    // 예약 정보 조회 메서드
    public void displayReservationInfo (String name){

        // 평탄화 작업, 2차원 배열을, 하나의 스트림안에 평면화해버림
                List<Reservation> reservations =Arrays.stream(seats).
                        flatMap(Arrays::stream)
                        .filter(reservation -> reservation != null)
                        .filter(reservation -> reservation.getCustomerName().equals(name))
                        .toList();

        System.out.println("예약 정보 >> ");

        for(Reservation reservation : reservations){
                System.out.println();
                System.out.println("좌석: "+ reservation.getRow()+ reservation.getCol());
                System.out.println("이름: "+ reservation.getCustomerName());
                System.out.println("전화번호: " + reservation.getCustomerPhoneNumber());

        }
    }

참고

참고로 seats[][]는 예약이 없는곳은 null로 되어있는데
그 점을 깜빡하고 filter 걸어줄때 reservation.getCustomerName().equals(name)만 걸어주니까

자꾸 NullPointExeption이 터졌다.
(null인데 getCustomerName() 해주려고 하니깐...)
항상 Null을 생각하자

filter로 null을 제외하지 않았을때

  // 예약 정보 조회 메서드
    public void displayReservationInfo (String name){

        // 평탄화 작업, 2차원 배열을, 하나의 스트림안에 평면화해버림
        // filter로 null을 제외하지 않았을때
                List<Reservation> reservations =Arrays.stream(seats).
                        flatMap(Arrays::stream)
                        .filter(reservation -> reservation != null)
                        .filter(reservation -> reservation.getCustomerName().equals(name))
                        .toList();

        System.out.println("예약 정보 >> ");

        for(Reservation reservation : reservations){
                System.out.println();
                System.out.println("좌석: "+ reservation.getRow()+ reservation.getCol());
                System.out.println("이름: "+ reservation.getCustomerName());
                System.out.println("전화번호: " + reservation.getCustomerPhoneNumber());

        }
    }

profile
엉성해도 우직하게

1개의 댓글

comment-user-thumbnail
2025년 4월 28일

제일 아래 코드랑 그 위에 코드랑 일부러 똑같이 둔건가요?

답글 달기