티스토리 뷰

반응형

Java Stream 사용 시, debugging이 어려울 때가 있다.

IntelliJ IDEA에서는 Stream debugging 시 시각적으로 데이터를 확인할 수 있는 기능을 제공하고 있는데, 이게 정말 편리하다. 이를 활용해보자.

 

예제

간단한 예제를 만들었다. (참고: Java 17 (LTS) 을 사용했다)

public static void main(String[] args) {
    var people = List.of(
            new Person("Sim", 47, City.SEOUL),
            new Person("Lee", 31, City.BUSAN),
            new Person("Kim", 23, City.SEOUL),
            new Person("Park", 18, City.JEJU),
            new Person("Song", 52, City.SEOUL)
    );

    var peopleNameInSeoul = people.stream()
            .filter(person -> person.city() == City.SEOUL)
            .sorted(Comparator.comparingInt(Person::age))
            .map(Person::name)
            .toList();

    System.out.println("peopleNameInSeoul = " + peopleNameInSeoul);
}

public enum City {
    SEOUL,
    BUSAN,
    JEJU,
}

public record Person(String name, int age, City city) {
}
  • record 가 생소할 수 있는데, 불변객체(final field)/ getter(필드와 같은 이름의 메서드)/ equals/ hashCode/ toString 가 자동으로 구현되는 클래스라고 보면 된다.
    • 참조
 

Java Language Updates

JDK 14 introduces records, which are a new kind of type declaration. Like an enum, a record is a restricted form of a class. It’s ideal for "plain data carriers," classes that contain data not meant to be altered and only the most fundamental methods suc

docs.oracle.com

 

핵심은 people.stream() 인데 지금은 로직이 너무 단순하다보니 눈으로 디버깅이 된다. 어렵게 하기 위해 내부 로직을 다 메서드로 빼냈다. 그래서 결국 아래와 같다.

public static void main(String[] args) {

    var people = List.of(
            new Person("Sim", 47, City.SEOUL),
            new Person("Lee", 31, City.BUSAN),
            new Person("Kim", 23, City.SEOUL),
            new Person("Park", 18, City.JEJU),
            new Person("Song", 52, City.SEOUL)
    );

    var peopleNameInSeoul = people.stream()
            .filter(someFilterLogic())
            .sorted(someSortedComparator())
            .map(getNameSomeLogic())
            .toList();

    System.out.println("peopleNameInSeoul = " + peopleNameInSeoul);
}

public enum City {
    SEOUL,
    BUSAN,
    JEJU,
}

public record Person(String name, int age, City city) {
}

 


보통의 경우

보통의 경우, break point를 설정하고 debugging을 하게 된다.

예시로 sorted(someSortedComparator()) 의 결과가 어떻게 될까?

위 사진처럼 break point를 찍고 넘겨보아도 각 Intermediate operation에서의 결과를 볼 수 없다. 당연히도 사용되는 객체들의 변화도 보여지지 않는다.

Step into 같은 다음 단계(라인)로 넘어가면서 보아도 사실 변화되는게 없다. 로직이 복잡하다면 뭔가 중간 중간 찍히는게 있을 수 있지만, Stream 데이터들의 변화 및 상태를 한 눈에 보기 쉽지 않다.

 


Trace Current Stream Chain

이럴 때 사용할 수 있는 것이 Trace Current Stream Chain 이다.

사용법은 비슷한데, 일단은 Stream 로직에 Break point를 찍고 Debugging을 실행한다.

 

IntelliJ의 Debug 창에서 위 사진의 빨간색 원에 해당하는 Trace Current Stream Chain 버튼을 클릭한다.

 

그러면 아래처럼 Stream 로직을 한눈에 볼 수 있게 된다.

Stream 로직에 들어오는 데이터는 어떻게 되는지, 각 단계별로 데이터는 어떻게 변화했는지, 어떤 데이터들이 필터되었는지 등 각 Stream intermediate operation의 결과를 확인할 수 있다.

 

각 단계 별 말고 정말 모든 Stream operation들을 한 눈에 보고 싶다면 왼쪽 아래의 Flat Mode 를 선택한다.

어떠한 데이터들이 남았고, 변화했는지 등 한 눈에 보기 좋게 제공한다.

 


 

IntelliJ에서 제공되는 기능들은 정말 다양하고 많다. 개발 시에 이를 얼마나 알고 활용하는가도 생산성에 막대한 영향을 끼치는 것 같다. 오늘의 글처럼 새로운 기능들을 공부하면서 조금씩 기록해두어야겠다.

320x100
반응형
댓글
반응형
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함