programing

람다 식을 사용하여 stream().map(...)을 디버깅하는 방법

nicescript 2022. 10. 30. 16:03
반응형

람다 식을 사용하여 stream().map(...)을 디버깅하는 방법

프로젝트에서는 Java 8로 이행하여 새로운 기능을 테스트하고 있습니다.

에서는 Guava 하여 Guava를 하여 몇 가지 컬렉션을 Collections2.transform ★★★★★★★★★★★★★★★★★」Collections2.filter

이 이행에서는 예를 들어 guava 코드를 java 8로 변경해야 합니다.제가 하고 있는 변화는 다음과 같습니다.

List<Integer> naturals = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10,11,12,13);

Function <Integer, Integer> duplicate = new Function<Integer, Integer>(){
    @Override
    public Integer apply(Integer n)
    {
        return n * 2;
    }
};

Collection result = Collections2.transform(naturals, duplicate);

~에 대해서...

List<Integer> result2 = naturals.stream()
    .map(n -> n * 2)
    .collect(Collectors.toList());

하면 각 수 때문에 디버깅할 수 만, guava를 입니다..map(n -> n*2).

디버거를 사용하면 다음과 같은 코드를 볼 수 있습니다.

@Hidden
@DontInline
/** Interpretively invoke this form on the given arguments. */
Object interpretWithArguments(Object... argumentValues) throws Throwable {
    if (TRACE_INTERPRETER)
        return interpretWithArgumentsTracing(argumentValues);
    checkInvocationCounter();
    assert(arityCheck(argumentValues));
    Object[] values = Arrays.copyOf(argumentValues, names.length);
    for (int i = argumentValues.length; i < values.length; i++) {
        values[i] = interpretName(names[i], values);
    }
    return (result < 0) ? null : values[result];
}

않습니다. Guava는 수 . 이데올로기 때문에n * 2★★★★★★ 。

이 변환을 확인할 수 있는 방법이나 이 코드를 쉽게 디버깅할 수 있는 방법이 있습니까?

편집: 다른 댓글에서 답변을 추가하고 답변을 올렸습니다.

★★님입니다.Holger, 을 갖는 에 의해 본문 수 되었습니다.

.map(
    n -> {
        Integer nr = n * 2;
        return nr;
    }
)

★★님입니다.Stuart Marks메서드 참조를 사용하는 접근방식에서는 변환 프로세스를 디버깅할 수도 있습니다.

static int timesTwo(int n) {
    Integer result = n * 2;
    return result;
}
...
List<Integer> result2 = naturals.stream()
    .map(Java8Test::timesTwo)
    .collect(Collectors.toList());
...

★★님입니다.Marlon Bernardes답변: Eclipse는 무엇을 해야 하는지 보여주지 않고 peek()를 사용하면 결과를 표시할 수 있습니다.

보통 이클립스나 인텔리J IDEA를 사용하는 동안 람다 식을 디버깅하는 데 문제가 없습니다.중단점을 설정하고 전체 람다 식을 검사하지 마십시오(람다 본체만 검사).

Lambdas 디버깅

하나의 은 '보다 낫다'입니다.peek「 」 「 」 소사 :

List<Integer> naturals = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12,13);
naturals.stream()
    .map(n -> n * 2)
    .peek(System.out::println)
    .collect(Collectors.toList());

갱신:

것 요.map는 입니다.intermediate operation- 다시 말하면, 이 작업은 느린 작업이며, 다음 작업 후에만 실행됩니다.terminal operation실행되었습니다. 했을 때stream.map(n -> n * 2)람다 바디는 현재 실행되고 있지 않습니다.(「」).collect(동료)

자세한 내용은 Stream Operations를 참조하십시오.

업데이트 2:

Holger의 코멘트를 인용합니다.

여기서 문제가 되는 것은 매핑 콜과 람다 표현은 한 줄에 있기 때문에 전혀 관련이 없는2개의 액션으로 회선 중단점이 정지됩니다.

바꿈 바로 에 줄 map(람다 식에 대해서만 중단점을 설정할 수 있습니다.가 나타내지 것은 일이 .return changing. 람다를 다다로 변경하다n -> { int result=n * 2; return result; }결과를 확인할 수 있습니다.다시 한 줄씩 밟을 때 줄 바꿈을 적절히 삽입하십시오.

IntelliJ에는 Java Stream Debugger 플러그인과 같은 훌륭한 플러그인이 있습니다.https://plugins.jetbrains.com/plugin/9696-java-stream-debugger?platform=hootsuite 를 확인해 주세요.

이는 IDEA Debugger 툴 창을 확장합니다.Trace Current Stream Chain 버튼은 Stream API 호출 체인의 내부에서 디버거가 정지하면 활성화됩니다.

개별 스트림 조작에 적합한 인터페이스를 갖추고 있어 디버깅해야 할 값을 따를 수 있습니다.

Java 스트림 디버거

[디버깅(Debug)]창에서 수동으로 시작하려면 여기를 클릭하십시오.

여기에 이미지 설명 입력

램다 디버깅은 NetBeans에서도 잘 동작합니다.NetBeans 8과 JDK 8u5를 사용하고 있습니다.

람다가 있는 선에 중단점을 설정하면 파이프라인이 설정될 때 실제로 한 번 히트한 다음 각 스트림 요소에 대해 한 번 히트합니다.예에서 은 " " " 입니다.map()「 」 「 」 、 「 」

제1 브레이크 포인트

과 로컬 및 할 수 .main가 다시 에 있습니다.스텝을 계속하면 같은 브레이크 포인트가 다시 히트합니다.단, 이번에는 람다 호출 내에 있습니다.

여기에 이미지 설명 입력

콜 내부 이며, lamda의 변수가 .main ( (어느쪽이든)naturals」를 참조해 주세요).

Marlon Bernardes가 지적한 바와 같이,peek파이프라인의 값을 검사합니다.병렬 스트림에서 사용하는 경우에는 주의해야 합니다.값은 여러 스레드 간에 예측할 수 없는 순서로 인쇄될 수 있습니다. peek데이터 구조는 물론 스레드 세이프가 필요합니다.

마지막으로 lamda(특히 multi-line statement lamda)의 디버깅을 많이 하는 경우에는 lamda를 명명된 메서드로 추출한 후 메서드 참조를 사용하여 참조하는 것이 좋습니다.예를들면,

static int timesTwo(int n) {
    return n * 2;
}

public static void main(String[] args) {
    List<Integer> naturals = Arrays.asList(3247,92837,123);
    List<Integer> result =
        naturals.stream()
            .map(DebugLambda::timesTwo)
            .collect(toList());
}

이렇게 하면 디버깅 중에 무슨 일이 일어나고 있는지 쉽게 알 수 있습니다.또한 이러한 방법으로 방법을 추출하면 단위 테스트가 더 쉬워집니다.람다가 너무 복잡해서 한 단계씩 진행해야 하는 경우에는 여러 가지 단위 테스트를 거쳐야 할 수도 있습니다.

더 업데이트된 세부 정보를 제공하기 위해(2019년 10월) IntelliJ는 매우 유용한 이런 종류의 코드를 디버깅하기 위해 꽤 훌륭한 통합을 추가했습니다.

(스텝을 누르면) 람다가 포함된 행에서 정지하면 디버깅할 스니펫이 IntelliJ에 강조 표시됩니다.디버깅할 청크를 전환할 수 있으며 이를 결정한 후 다시 클릭합니다.

다음은 몇 가지 스크린샷을 보여드리겠습니다.

1-(스텝 입력) 키를 누르면 강조 표시(또는 선택 모드)가 표시됩니다.

2-여러 번 사용하여 디버깅할 스니펫을 선택합니다.

3 - 키를 눌러 (스텝 입력)에 들어갑니다.

Intelij IDEA 15는 lambda가 있는 행의 일부에서 정지할 수 있습니다.첫 번째 기능은 http://blog.jetbrains.com/idea/2015/06/intellij-idea-15-eap-is-open/ 입니다.

IDE를 사용한 디버깅은 항상 도움이 되지만 스트림 내의 각 요소를 통해 디버깅하는 이상적인 방법은 Java 스팀 평가가 느리기 때문에 터미널 메서드 조작 전에 peek()를 사용하는 것입니다.따라서 터미널 메서드가 호출되지 않는 한 각 스트림은 평가되지 않습니다.

List<Integer> numFromZeroToTen = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

    numFromZeroToTen.stream()
        .map(n -> n * 2)
        .peek(n -> System.out.println(n))
        .collect(Collectors.toList());

언급URL : https://stackoverflow.com/questions/24541786/how-to-debug-stream-map-with-lambda-expressions

반응형