JavaRush /Java Blog /Random-KO /단순하지 않은 단순 흐름
Oleg Savenko
레벨 41
Одесса

단순하지 않은 단순 흐름

Random-KO 그룹에 게시되었습니다
Java의 새 버전이 나올 때마다 Java는 더욱 풍부해집니다. 많은 기능이 이전 버전에 있지만 언어는 방법론과 구현 측면에서 계속해서 개선되었습니다. Java의 컬렉션도 예외는 아닙니다. 핵심 컬렉션 프레임워크는 J2SE 1.2에 등장했고 실망스럽기보다는 즐거운 변화를 겪으면서 계속 발전했습니다. JDK 5가 출시되면서 컬렉션은 더욱 편리해지고, 빨라지고, 작업하기 쉬워졌습니다. 이로 인해 프로그래머는 이를 더욱 집중적으로 활용하기 시작했습니다. 의심의 여지 없이 효과적인 특정 패턴이 개발되었습니다. 그러나 JDK 8에서는 컬렉션이 다시 좋아졌고 스레드 덕분에 더 좋아졌습니다. 분명히 컬렉션이 스트림 형태로 표현될 수 있다는 사실로 인해 컬렉션을 사용하는 방법도 변경될 것입니다. 따라서 컬렉션을 사용한 친숙하고 이해하기 쉬운 솔루션이 어떻게 더욱 단순해지는지 보여주고 싶습니다.

예시 1. 이보다 더 간단할 수는 없습니다

물론 가장 간단한 것부터 시작해 컬렉션의 모든 요소를 ​​살펴보고 모든 요소를 ​​표시해 보겠습니다.
// создадим и заполним список
   List<Integer> list = new ArrayList<>();
   Collections.addAll(list, 1, 5, 6, 11, 3, 15, 7, 8);
   // а теперь
   // быстрый for по всем elementм, только для коллекций
   for (Integer i:list){
       System.out.println(i);
   }
   //но мы уже живем в JDK 8
   //а значит нужно так
   list.stream().forEach(System.out::println);
아시다시피, Java 초보자인 제 생각에는 훨씬 더 간단한 새로운 구문이 있습니다. 따라서 새 구문에서 볼 수 있는 내용은 다음과 같습니다.
берем_список(list).превращаем_в_поток(stream).перебираем_все_элементы(forEach)(тут_интуитивно_понятно)
System.out::println— 콘솔에 문자열을 출력하는 정적 메서드에 대한 링크 정적 메서드에 대한 링크 대신 약간 다르고 덜 명확한 항목을 사용할 수 있습니다.
list.stream().forEach(i -> System.out.println(i));
이 항목은 람다 표현식을 사용합니다. 그리고 그렇습니다. 스트림 작업 방법을 배우려면 람다 표현식을 배워야 합니다. 정말 훌륭합니다. 또한 이 과정을 진행하는 동안 전통적인 방법에 익숙해졌기 때문에 스트림만 사용하여 컬렉션으로 작업하는 방법을 보여주지는 않겠습니다.

예시 2. 목록에서 짝수 값을 찾아 콘솔에 표시

list.stream().filter(i -> i%2==0).forEach(System.out::println);
전체 문제는 한 줄로 해결되었습니다. 한줄로 즐겁게 일하시길 바랍니다. 이 방법을 사용하여 filter스트림을 필터링하고 남은 내용을 콘솔에 출력했습니다. 필터는 가장 예상치 못한 경우에 도움이 될 수 있는 매우 강력한 기능입니다. 창의력을 발휘하여 문제의 조건을 바꾸자. 예를 들어, 목록에 짝수가 몇 개 있는지 계산해야 합니다.
long count = list.stream().filter(i -> i%2==0).count();
그리고 다시 한 줄로. 어쩐지 모든 것이 단순해 보입니다. 필터에서는 람다 표현식을 사용하여 새 스트림에 짝수만 배치한 다음 새 스트림에 적용하여 count새 스트림에 요소가 몇 개 있는지 계산했습니다.

예시 3. 목록에서 5자 길이의 단어 수를 세어 보겠습니다.

우리는 정수를 가지고 놀았으니 이제 단어를 가지고 놀아봅시다.
List<String> list = new ArrayList<>();
Collections.addAll(list, "разые", "слова", "интересные", "And", "Not", "Very");

System.out.println(list.stream().filter(w -> w.length() == 5).count());
필터를 다시 사용했습니다. 필터에는 람다 표현식을 사용하여 새 스트림이 표시되었으며, 당연히 count새 스트림에 몇 개의 요소가 있는지 계산했습니다.

예시 4. 고유한 단어 인쇄

파일에서 컬렉션으로 다양한 단어를 읽을 때 익숙한 작업이지만 이제는 고유한 단어만 필요합니다.
List<String> list = new ArrayList<>();
Collections.addAll(list, "Vasya", "Таня", "Olya", "Vasya", "Olya", "Сергей");

list.stream().distinct().forEach(System.out::println);
주요 작업은 를 사용하여 스트림에서 수행되었습니다 distinct. 다음으로, 스레드를 사용하여 과정의 일부 작업을 살펴보는 것이 좋습니다.

예시 5. 긴 단어

Java Core의 9번째 레벨인 강의 11에는 흥미로운 문제가 있습니다. File2에 쉼표로 구분된 단어를 작성해야 하는데, 그 길이는 엄밀히 말하면 6보다 큽니다. 어떤 종류의 정원에 펜싱을 하든, 나는 다음과 같은 해결책을 제안합니다.
  1. 소스 파일에서 목록의 모든 단어를 읽습니다.

  2. 그런 다음 다음 줄을 실행합니다.

    Optional<String> rezult = list.stream()
    				.filter(w->w.length()>6)
    				.reduce((w1,w2)->w1+", "+w2);
  3. result.get()파일에 씁니다.

스레드를 사용한 흥미로운 솔루션이 있습니다. 필터를 필터링하고 축소 및 정규식을 사용하여 필요한 문자열이 생성되었습니다.

예시 6. 숫자가 포함된 단어

File2에는 숫자가 포함된 모든 단어(예: a1 또는 abc3d)를 공백으로 구분하여 작성합니다. 이것은 또한 우리 문제집의 조건이기도 합니다. 짐작하셨듯이 해결책은 간단합니다.
Optional<String> rezult = list.stream()
				.filter(w->w.matches(".*?\\d+.*?"))
				.reduce((w1,w2)->w1+" "+w2);
정규식을 사용하여 스트림을 필터링한 다음 축소 및 람다 식을 사용했습니다. 이전 작업과 공통점이 많습니다.

예시 7. 숫자 선택

전체 작업은 다음과 같습니다.
  • 콘솔에서 2개의 파일 이름을 읽습니다.
  • 첫 번째 파일에 있는 모든 숫자를 두 번째 파일에 출력합니다.
  • 숫자는 공백으로 구분됩니다.
  • 스트림을 닫습니다.
공백으로 구분된 문자열에 숫자를 쓰는 주요 작업의 경우 파일에 추가로 쓰기 위해 스트림을 사용하는 것이 좋습니다. 다음과 같습니다.
Optional<String> rezult = list.stream().filter(w->w.matches("\\d+"))
				.reduce((w1,w2)->w1+" "+w2);
System.out.println(rezult.get());
스레드를 사용하면 매우 간단한 방법으로 문제가 해결됩니다. 그러나 보라, 이 솔루션을 이전의 두 가지 솔루션과 직접 비교해 보십시오. 기사를 마치며 여러분에게 고백하고 싶습니다. 여러분, 제가 예를 선택할 때 속임수를 썼습니다. 사실 저는 여러분에게 익숙한 문제를 사용하여 익숙하지 않은 주제를 보여주기 위해 가장 간단한 예를 선택했습니다. 물론 스레드는 간단한 작업과 복잡한 작업 모두에 사용됩니다. 그러나 Horstman이 자신의 책에서 강조한 것처럼 "데이터 흐름은 "무엇을 해야 하는지가 아니라 무엇을 해야 하는지"라는 원칙에 따라 작동합니다. 이는 이전에 복잡했던 많은 작업이 더 간단해질 수 있음을 의미합니다. 나는 당신에 대해 모르지만 흐름이 마음에 들었고 당신이 그것을 배우는 것을 방해하지 않았기를 바랍니다. 그리고 한 가지 더 설명하겠습니다.
  1. 나는 독자들에게 컬렉션에서 스트림을 사용하는 방법을 가르치려고 시작한 것이 아니며, 그렇게 경험이 풍부한 교사도 아닙니다. 스레드가 간단하고 매우 흥미롭다는 것을 보여주고 싶었습니다! 일반적으로 이는 필수입니다.
  2. 흐름을 더 많이 이해할수록 교과서의 모든 문제를 해결하는 문제가 더 많이 보입니다. 이는 흐름이 헛되지 않았다는 것을 의미합니다.
  3. 스트림은 작업하기 쉬울 뿐만 아니라 중요한 이점도 있습니다. 즉, 대량의 데이터로 작업할 때 스트림의 생산성이 더 높은 경우가 많습니다.
추신 . 나는 모든 문제에 대해 농담을 하고 있었습니다. 권장사항: 전문 Java 라이브러리. 2권 고급 프로그래밍 도구. 케이 호스트만. 나는 열 번째 판을 가지고 있습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION