program story

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

inputbox 2020. 8. 11. 08:25
반응형

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


인터뷰에서이 질문을 받았는데 제가 가질 수있는 최선의 답변을했는지 확신 할 수 없습니다. 병렬 검색을 수행 할 수 있으며 기억할 수없는 방법으로 null 값이 처리되었다고 언급했습니다. 이제 선택 사항을 생각하고 있다는 것을 깨달았습니다. 내가 여기서 무엇을 놓치고 있습니까? 그들은 그것이 더 낫거나 더 간결한 코드라고 주장하지만 나는 동의하는지 확신하지 못합니다.


얼마나 간결하게 대답했는지를 고려할 때 이것은 결국 너무 광범위한 질문이 아닌 것 같습니다.


그들이 인터뷰에서이 질문을하고 있고 그것이 분명하다면, 답을 찾기 어렵게 만드는 것 외에 어떤 목적으로 그것을 분해 할 수 있습니까? 당신은 무엇을 찾고 있습니까? 나는 질문을 세분화하고 모든 하위 질문에 답할 수 있지만 모든 하위 질문에 대한 링크가있는 상위 질문을 생성 할 수 있습니다. 그래도 꽤 어리석은 것 같습니다. 그동안 좀 덜 광범위한 질문의 예를 들어주세요. 이 질문의 일부만 물어도 여전히 의미있는 답을 얻을 수있는 방법이 없습니다. 다른 방식으로 정확히 같은 질문을 할 수 있습니다. 예를 들어 "스트림이 제공되는 목적은 무엇입니까?"라고 물을 수 있습니다. 또는 "for 루프 대신 스트림을 언제 사용합니까?" 또는 "왜 for 루프 대신 스트림을 사용합니까?" 이것들은 모두 똑같은 질문입니다.

... 또는 누군가가 정말 긴 다 지점 답변을했기 때문에 너무 광범위하다고 간주됩니까? 솔직히 아는 사람이라면 거의 모든 질문으로 그렇게 할 수 있습니다. 예를 들어, JVM의 작성자 중 한 명이라면 우리 대부분이 할 수없는 하루 종일 for 루프에 대해 이야기 할 수 있습니다.

"적절한 답변을 식별 할 수있는 충분한 세부 정보가있는 특정 문제로 제한하도록 질문을 편집하십시오. 한 번에 여러 개의 개별 질문을하지 마십시오.이 질문을 명확히하려면 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;

"I 'm doing a loop"라고 말합니다. 루프의 목적은 논리에 더 깊이 묻혀 있습니다.

스트림은 종종 간결 합니다. 동일한 예가이를 보여줍니다. 간결한 것이 항상 좋은 것은 아니지만 간결하고 표현력이 동시에 가능하다면 훨씬 좋습니다.

스트림은 기능과 강한 친화력을 가지고 있습니다 . Java 8은 강력한 기술의 전체 장난감 상자를 여는 람다 및 기능 인터페이스를 도입합니다. 스트림은 객체 시퀀스에 함수를 적용하는 가장 편리하고 자연스러운 방법을 제공합니다.

스트림은 변경 가능성을 낮 춥니 다 . 이것은 함수형 프로그래밍 측면과 관련이 있습니다. 스트림을 사용하여 작성하는 프로그램의 종류는 객체를 수정하지 않는 종류의 프로그램 인 경향이 있습니다.

스트림은 느슨한 결합을 권장 합니다. 스트림 처리 코드는 스트림의 소스 또는 최종 종료 방법을 알 필요가 없습니다.

스트림은 매우 정교한 동작을 간결하게 표현할 수 있습니다 . 예를 들면 :

 stream.filter(myfilter).findFirst();

전체 스트림을 필터링 한 다음 첫 번째 요소를 반환하는 것처럼 한 눈에 볼 수 있습니다. 그러나 실제로 findFirst()전체 작업을 주도하므로 하나의 항목을 찾은 후 효율적으로 중지됩니다.

스트림은 향후 효율성 향상을위한 범위를 제공합니다 . 일부 사람들은 인 메모리 List또는 어레이의 단일 스레드 스트림 이 동등한 루프보다 느릴 수 있음 을 벤치마킹하고 발견했습니다 . 이것은 더 많은 물체와 오버 헤드가 있기 때문에 그럴듯합니다.

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

단점?

성능 : for배열을 통한 루프는 힙 및 CPU 사용량 측면에서 매우 가볍습니다. 원시 속도와 메모리 절약이 우선이라면 스트림을 사용하는 것이 더 나쁩니다.

익숙 함 세상은 루프가 익숙하고 스트림이 참신한 많은 언어 배경을 가진 숙련 된 절차 프로그래머로 가득 차 있습니다. 어떤 환경에서는 그런 사람에게 익숙한 코드를 작성하려고합니다.

인지 오버 헤드 . 선언적 특성과 그 아래에서 일어나는 일의 추상화가 증가했기 때문에 코드가 실행과 어떻게 관련되는지에 대한 새로운 정신 모델을 구축해야 할 수도 있습니다. 실제로는 일이 잘못되거나 성능이나 미묘한 버그를 심층 분석해야 할 때만이 작업을 수행하면됩니다. "그냥 작동"하면 작동합니다.

디버거 가 개선되고 있지만 지금도 디버거에서 스트림 코드를 단계별로 실행할 때 간단한 루프가 기존 디버거가 작동하는 변수 및 코드 위치에 매우 가깝기 때문에 동일한 루프보다 작업이 더 어려울 수 있습니다.


구문 재미를 제외하고 Streams는 잠재적으로 무한히 큰 데이터 세트와 함께 작동하도록 설계되었지만 배열, 컬렉션 및 Iterable을 구현하는 거의 모든 Java SE 클래스는 전적으로 메모리에 있습니다.

Stream의 단점은 필터, 매핑 등이 확인 된 예외를 throw 할 수 없다는 것입니다. 이로 인해 Stream은 중간 I / O 작업에 적합하지 않습니다.


  1. 당신은 잘못 깨달았습니다 : 병렬 연산은 Streams가 아니라 Optionals를 사용합니다.

  2. 스트림과 함께 작동하는 메소드를 정의 할 수 있습니다. 매개 변수로 취하거나 반환하는 등의 작업을 할 수 있습니다. 루프를 매개 변수로 사용하는 메소드는 정의 할 수 없습니다. 이를 통해 복잡한 스트림 작업을 한 번에 여러 번 사용할 수 있습니다. Java에는 여기에 단점이 있습니다. 메소드 someMethod(stream)를 스트림 자체와 반대로 호출해야 stream.someMethod()하므로 이들을 혼합하면 읽기가 복잡해집니다. 작업 순서를 확인하십시오.

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

    다른 많은 언어 (C #, Kotlin, Scala 등)에서는 일종의 "확장 메서드"를 허용합니다.

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


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.


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.

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

반응형