JavaRush /Java Blog /Random-KO /Java 8에서 루프 제거
KapChook
레벨 19
Volga

Java 8에서 루프 제거

Random-KO 그룹에 게시되었습니다
Java 8에 도입된 기능적 스타일은 언어에 큰 도움이 됩니다. 이제 Java는 순수한 OOP가 아니며 OOP와 함수형 프로그래밍의 하이브리드입니다. 이것은 게임 체인저이며 이러한 변화를 흡수하려면 OOP 두뇌를 바꿔야 합니다. Java 8 - 1에서 루프 제거하기그런데 왜 우리는 이러한 변화를 받아들여야 할까요? 순수 OOP를 사용하여 문제를 해결할 수 있는데 왜 함수형 스타일과 어울리려고 시간을 낭비해야 합니까?
  • Java 8에 도입된 기능적 스타일은 비즈니스 로직과 코드 간의 격차를 줄이는 데 도움이 됩니다. 이를 통해 더 높은 수준에서 자연스러운 흐름으로 이야기를 전달할 수 있습니다. 어떻게 하고 싶은지 말하는 대신, 무엇을 하고 싶은지 말할 수 있습니다.

  • 코드가 더 깔끔하고 간결해졌습니다.

  • 고차 함수를 사용하면 다음을 수행할 수 있습니다.

    • 함수를 다른 함수로 보내기
    • 다른 함수 안에 함수 만들기
    • 다른 함수의 함수 반환

    이는 이를 수행하기 위해 객체를 보내고, 생성하고, 반환해야 하는 Java의 큰 승리입니다. 우리는 더욱 안정적이고 집중적이며 재사용하기 쉬운 코드를 작성할 수 있을 것입니다.

  • 람다 덕분에 우리는 게으른 계산을 할 수 있습니다. 람다 식이 메서드 인수로 전송되면 컴파일러는 메서드에서 호출될 때 이를 평가합니다. 이는 즉시 평가되는 일반 메서드 인수와 다릅니다.

  • 람다는 단위 테스트 작성을 재미있게 만듭니다. 이를 통해 깨끗하고 크기가 작으며 작성이 빠른 경량 테스트를 만들 수 있습니다. 람다를 사용하여 테스트 중인 코드를 근절할 수 있습니다. 이를 통해 모든 종류의 시나리오가 코드에 어떤 영향을 미치는지 테스트할 수 있습니다.

  • 배울 수 있는 새로운 패턴.

  • 그리고 훨씬 더!

하지만 물은 충분합니다. 이 기사에서는 기존 사이클에 대한 대체 솔루션을 살펴보겠습니다. 물론 주기는 유연하지만 대가가 따르지 않는 것은 아닙니다. break, 루프의 동작을 극적으로 변경하여 코드가 달성하려는 내용뿐만 continue아니라 return루프가 작동하는 방식도 이해하도록 합니다. 이제 루프를 보다 간결하고 읽기 쉬운 코드로 변환하는 방법을 살펴보겠습니다.

코딩을 시작해 보세요!

우리는 기사로 작업할 것입니다. 기사에는 제목, 작성자 및 여러 태그가 있습니다.
private class Article {

    private final String title;
    private final String author;
    private final List<String> tags;

    private Article(String title, String author, List<String> tags) {
        this.title = title;
        this.author = author;
        this.tags = tags;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public List<String> getTags() {
        return tags;
    }
}
각 예제에는 루프를 사용하는 기존 솔루션과 Java 8의 새로운 기능을 사용하는 솔루션이 포함됩니다. 첫 번째 예제에서는 "Java" 태그가 있는 컬렉션의 첫 번째 기사를 찾으려고 합니다. 루프를 사용한 솔루션을 살펴보겠습니다.
public Article getFirstJavaArticle() {

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            return article;
        }
    }
    return null;
}
이제 Stream API의 작업을 사용하여 문제를 해결해 보겠습니다.
public Optional<Article> getFirstJavaArticle() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .findFirst();
    }
정말 멋지지 않나요? 먼저 이 작업을 사용하여 filter"Java" 태그가 있는 모든 기사를 찾은 다음 findFirst()첫 번째 항목을 가져오는 데 사용합니다. 스트림은 게으르고 필터는 스트림을 반환하므로 이 접근 방식은 첫 번째 일치 항목을 찾을 때까지 요소만 처리합니다. 이제 첫 번째 기사 대신 "Java" 태그가 지정된 모든 기사를 가져오겠습니다. 먼저 루프를 사용하는 솔루션입니다.
public List<Article> getAllJavaArticles() {

    List<Article> result = new ArrayList<>();

    for (Article article : articles) {
        if (article.getTags().contains("Java")) {
            result.add(article);
        }
    }
    return result;
}
스트림 작업을 사용하는 솔루션입니다.
public List<Article> getAllJavaArticles() {
    return articles.stream()
        .filter(article -> article.getTags().contains("Java"))
        .collect(Collectors.toList());
    }
collect이 예에서는 컬렉션을 선언하고 일치하는 항목을 명시적으로 추가하는 대신 결과 스트림을 단축하는 작업을 사용했습니다 . 여태까지는 그런대로 잘됐다. Stream API를 정말 빛나게 만드는 예제를 살펴볼 시간입니다. 모든 기사를 작성자별로 그룹화해 보겠습니다. 평소와 같이 루프를 사용하여 문제를 해결하는 것으로 시작합니다.
public Map<String, List<Article>> groupByAuthor() {

    Map<String, List<Article>> result = new HashMap<>();

    for (Article article : articles) {
        if (result.containsKey(article.getAuthor())) {
            result.get(article.getAuthor()).add(article);
        } else {
            ArrayList<Article> articles = new ArrayList<>();
            articles.add(article);
            result.put(article.getAuthor(), articles);
        }
    }
    return result;
}
스트림 작업을 사용하여 이 문제에 대한 명확한 해결책을 찾을 수 있습니까?
public Map<String, List<Article>> groupByAuthor() {
    return articles.stream()
        .collect(Collectors.groupingBy(Article::getAuthor));
}
놀라운! 연산 groupingBy과 메소드 참조를 사용하여 getAuthor()깨끗하고 읽기 쉬운 코드를 얻습니다. 이제 컬렉션에 사용된 나머지 태그를 찾아보겠습니다. 루프 예제부터 시작해 보겠습니다.
public Set<String> getDistinctTags() {

    Set<String> result = new HashSet<>();

    for (Article article : articles) {
        result.addAll(article.getTags());
    }
    return result;
}
이제 스트림 작업을 사용하여 이 문제를 어떻게 해결할 수 있는지 살펴보겠습니다.
public Set<String> getDistinctTags() {
    return articles.stream()
        .flatMap(article -> article.getTags().stream())
        .collect(Collectors.toSet());
}
시원한! flatmap태그 목록을 단일 결과 스트림으로 평면화한 다음 이를 사용하여 collect반환 세트를 만드는 데 도움이 됩니다.

끝없는 가능성

루프를 더 읽기 쉬운 코드로 대체할 수 있는 방법에 대한 4가지 예는 다음과 같습니다. 이 기사는 단지 표면적인 내용만 다루었으므로 Stream API를 확인하십시오. Java의 새로운 기능적 스타일을 마스터하는 것은 OOP 개발자에게 어려운 일이지만 반드시 받아들여야 할 도전입니다. 나는 더 나아가 순수 함수형 프로그래밍 언어를 배워야 한다고 말할 것입니다. 이렇게 하면 그것이 제공하는 기능과 힘을 완전히 이해할 수 있습니다. 이것이 다른 수준의 함수형 프로그래밍을 이해하는 데 도움이 될 것이라고 생각합니다. 그러니 오래된 OOP와 함께 함수형 프로그래밍을 배우고 두 가지를 모두 사용하여 훨씬 더 훌륭한 코드를 작성하세요! 두 기사의 무료 번역 혼합 - Java 8에서 함수형 프로그래밍을 채택해야 하는 이유Java 8의 루프에서 벗어나기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION