source

Java에서는 루프에 비해 스트림의 장점은 무엇입니까?

factcode 2022. 8. 16. 23:16
반응형

Java에서는 루프에 비해 스트림의 장점은 무엇입니까?

면접에서 이런 질문을 받았는데 제가 할 수 있는 최선의 답변을 드렸는지 모르겠습니다.병렬 검색을 할 수 있고 null 값이 제가 기억할 수 없는 방법으로 처리되었다고 말씀드렸습니다.내가 옵션들을 생각하고 있었다는 걸 깨달았어.내가 뭘 놓쳤지?그들은 그것이 더 낫거나 더 간결한 코드라고 주장하지만 나는 동의할 수 없다.


그것이 얼마나 간결하게 대답되었는지를 고려하면, 이것은 결국 너무 광범위한 질문이 아니었던 것 같다.


만약 그들이 면접에서 이 질문을 하고 있다면, 그리고 분명히 그렇다 하더라도, 답을 찾기 어렵게 만드는 것 외에 그것을 분해하는 것이 어떤 목적으로 도움이 될까요?내 말은, 뭘 찾는 거야?질문을 분해하여 모든 하위 질문에 대한 답변을 얻을 수 있지만 모든 하위 질문에 대한 링크가 포함된 상위 질문을 만들 수 있습니다.좀 바보같긴 한데내친김에 좀 덜 광범위한 질문의 예를 들어주세요.나는 이 질문의 일부만 물어보고 의미 있는 답변을 얻을 방법이 없다.다른 방법으로 똑같은 질문을 할 수도 있어요.예를 들어 "스트림은 어떤 용도로 사용됩니까?" 또는 "for loop 대신 스트림을 언제 사용해야 합니까?" 또는 "루프 대신 스트림을 사용하는 이유는 무엇입니까?"라고 질문할 수 있습니다.하지만 이것들은 모두 정확히 같은 질문이다.

...아니면 누군가가 너무 긴 멀티포인트 답변을 했기 때문에 너무 광범위하다고 생각되는 건가요?솔직히 아는 사람이라면 누구나 거의 모든 질문을 가지고 그것을 할 수 있다.예를 들어, JVM의 작성자 중 한 명이라면, 대부분의 사람들이 할 수 없는 루프에 대해 하루 종일 이야기할 수 있을 것입니다.

질문을 편집하여 특정 문제에 한정하고 적절한 답변을 특정할 수 있도록 충분히 상세하게 설명하십시오.한 번에 여러 개의 다른 질문을 하지 않도록 합니다.이 질문에 대한 자세한 내용은 How to Ask 페이지를 참조하십시오."

아래에 기술한 바와 같이, 적절한 답변이 제공되었고, 그것이 충분히 제공하기에 쉽다는 것을 증명하는 적절한 답변은 다음과 같습니다.

흥미로운 점은 면접 질문은 단점을 묻지 않고 장점에 대해 묻는 것인데, 둘 다 있기 때문이다.

스트림은 보다 선언적인 스타일입니다.아니면 좀 더 표현력 있는 스타일.그 방법을 설명하는 것보다 코드로 의사를 표명하는 것이 더 나을 수 있습니다.

 return people
     .filter( p -> p.age() < 19)
     .collect(toList());

...목록에서 일치하는 요소를 필터링하고 있음을 분명히 알 수 있습니다.단, 다음과 같습니다.

 List<Person> filtered = new ArrayList<>();
 for(Person p : people) {
     if(p.age() < 19) {
         filtered.add(p);
     }
 }
 return filtered;

"루프를 하고 있어요"라고 합니다.루프의 목적은 로직의 더 깊은 곳에 있습니다.

흐름은 종종 더 거칠다.같은 예에서 이것을 나타내고 있습니다.터서가 항상 좋은 것은 아니지만, 간결함과 표현을 동시에 할 수 있다면 훨씬 더 좋을 것이다.

스트림은 기능과 강한 어피니티를 가집니다.Java 8은 람다와 기능 인터페이스를 도입하여 강력한 기술의 완구 상자를 엽니다.스트림은 개체의 시퀀스에 함수를 적용할 수 있는 가장 편리하고 자연스러운 방법을 제공합니다.

스트림은 변동성을 줄여줍니다.이것은 기능적 프로그래밍의 측면과 관련이 있습니다.스트림을 사용하여 작성하는 프로그램의 종류는 오브젝트를 수정하지 않는 프로그램인 경우가 많습니다.

흐름은 느슨한 결합을 촉진합니다.스트림 처리 코드는 스트림의 소스나 스트림의 최종 종료 방법을 알 필요가 없습니다.

스트림은 꽤 정교한 행동을 간결하게 표현할 수 있다.예를 들어 다음과 같습니다.

 stream.filter(myfilter).findFirst();

언뜻 보면 전체 스트림을 필터링한 후 첫 번째 요소를 반환하는 것처럼 보입니다.근데 사실findFirst()전체 작업을 구동하기 때문에 하나의 항목을 찾은 후 효율적으로 정지합니다.

스트림을 통해 향후 효율성을 높일있습니다.일부 사용자가 벤치마크를 통해 인메모리에서 싱글 스레드 스트림이List또는 어레이는 동등한 루프보다 느릴 수 있습니다.이는 더 많은 객체와 오버헤드가 있기 때문에 타당합니다.

하지만 개울은 확장된다.병렬 스트림 연산에 대한 Java의 내장 지원뿐만 아니라 모델이 적합하기 때문에 Streams를 API로 사용하는 분산 맵 축소를 위한 라이브러리가 몇 개 있습니다.

단점?

퍼포먼스:afor어레이를 통과하는 루프는 힙과 CPU 사용률 모두에서 매우 가볍습니다.원시 속도와 메모리 절약성이 우선인 경우 스트림을 사용하는 것이 더 좋지 않습니다.

친숙함.세상에는 많은 언어 배경을 가진 숙련된 프로시저 프로그래머들이 가득합니다. 루프는 익숙하고 스트림은 참신합니다.환경에 따라서는, 그러한 사람에게 익숙한 코드를 작성하려고 하는 경우도 있습니다.

인지적 오버헤드.선언적인 성격과 그 아래에 일어나는 일들로부터 더 많은 추상화 때문에, 여러분은 코드가 어떻게 실행과 관련이 있는지에 대한 새로운 정신 모델을 구축할 필요가 있을지도 모릅니다.실제로 이 작업은 문제가 발생하거나 성능 또는 미묘한 버그를 자세히 분석해야 할 경우에만 필요합니다."그냥" 작동하면, 그냥 작동합니다.

디버거는 개선되고 있지만, 지금까지도 디버거에서 스트림 코드를 밟을 때는 기존 디버거가 사용하는 변수와 코드 위치에 매우 근접해 있기 때문에 동등한 루프보다 더 어려운 작업이 될 수 있습니다.

통사적인 재미는 차치하고, 스트림은 잠재적으로 무한히 큰 데이터 세트로 동작하도록 설계되어 있습니다.한편, 어레이, 컬렉션 및 Itable을 구현하는 거의 모든 Java SE 클래스는 완전히 메모리에 있습니다.

스트림의 단점은 필터, 매핑 등이 선택된 예외를 슬로우할 수 없다는 것입니다.따라서 스트림은 중간 I/O 작업에 적합하지 않습니다.

  1. 잘못 알고 있습니다.병행연산 사용Streams, 아니다Optionals.

  2. 스트림에 대한 메서드를 정의할 수 있습니다.이 메서드를 파라미터로 취득하거나 반환하거나 할 수 있습니다.루프를 매개 변수로 사용하는 메서드는 정의할 수 없습니다.이를 통해 복잡한 스트림 작업을 한 번 여러 번 수행할 수 있습니다.Java에는 단점이 있습니다.즉, 당신의 메서드는 다음과 같이 호출되어야 합니다.someMethod(stream)개울과 반대로stream.someMethod()를 혼합하면 판독이 복잡해집니다.의 조작 순서를 확인해 주세요.

    myMethod2(myMethod(stream.transform(...)).filter(...))
    

    그 외의 많은 언어(C#, Kotlin, Scala 등)에서는, 「확장 방식」을 사용할 수 있습니다.

  3. 스트림 또는 루프를 사용할 수 있도록 순차적인 작업만 필요하고 재사용을 원하지 않는 경우에도 스트림에 대한 간단한 작업은 루프의 매우 복잡한 변경에 해당할 수 있습니다.

I'd say its parallelization that is so easy to use. Try iterating over millions of entries in parallel with a for loop. We go to many cpus, not faster; so the easier it is to run in parallel the better, and with Streams this is a breeze.

What I like a lot is the verbosity they offer. It takes little time to understand what they actually do and produce as opposed of how they do it.

You loop over a sequence (array, collection, input, ...) because you want to apply some function to the elements of the sequence.

Streams give you the ability to compose functions on sequence elements and allow to implement most common functions (e.g. mapping, filtering, finding, sorting, collecting, ...) independent of a concrete case.

Therefore given some looping task in most cases you can express it with less code using Streams, i.e. you gain readability.

ReferenceURL : https://stackoverflow.com/questions/44180101/in-java-what-are-the-advantages-of-streams-over-loops

반응형