Nice programing

열거 형으로 작업하는 Java 8 방법

nicepro 2020. 12. 25. 22:55
반응형

열거 형으로 작업하는 Java 8 방법


열거 형의 모든 값을 사용하는 가장 좋은 방법이 Java 8에서 무엇인지 궁금합니다. 특히 모든 값을 가져 와서 어딘가에 추가해야하는 경우, 예를 들어 다음 열거 형이 있다고 가정합니다.

public enum Letter {
 A, B, C, D;
}

물론 다음을 수행 할 수 있습니다.

for (Letter l : Letter.values()) {
    foo(l);
}

그러나 열거 형 정의에 다음 메서드를 추가 할 수도 있습니다.

public static Stream<Letter> stream() {
    return Arrays.stream(Letter.values());
}

그런 다음 위의 for를 다음으로 바꿉니다.

Letter.stream().forEach(l -> foo(l));

이 접근 방식이 괜찮습니까, 아니면 디자인이나 성능에 결함이 있습니까? 또한 열거 형에 stream () 메서드가없는 이유는 무엇입니까?


세 가지 질문 : 세 부분으로 구성된 답변 :

디자인 관점에서 괜찮습니까?

물론. 문제가 없습니다. 열거 형에 대해 많은 반복 작업을 수행해야하는 경우 스트림 API가 깔끔한 방법이며 약간의 메서드 뒤에 보일러 플레이트를 숨기는 것이 좋습니다. OldCumudgeon버전 이 더 낫다고 생각하지만 .

성능의 관점에서 괜찮습니까?

그것은 거의 중요하지 않습니다. 대부분의 경우 열거 형은 그다지 크지 않습니다. 따라서 한 가지 방법에 대한 오버 헤드가 무엇이든 99.9 %의 경우에는 문제가되지 않습니다.

물론 0.1 %가 있습니다. 이 경우 : 실제 데이터와 소비자를 사용하여 적절하게 측정하십시오.

내기해야한다면 for each루프가 메모리 모델에 더 직접적으로 매핑되기 때문에 루프가 더 빠를 것으로 기대 하지만 성능을 말할 때 추측하지 말고 실제로 튜닝이 필요하기 전에 튜닝하지 마십시오. 먼저 올바른 방식으로 코드를 작성하고 두 번째로 읽기 쉬운 방식으로 코드를 작성한 다음 코드 스타일의 성능에 대해 걱정하십시오.

Enum이 Stream API에 제대로 통합되지 않는 이유는 무엇입니까?

Java의 Stream API를 다른 많은 언어의 해당 API와 비교하면 심각하게 제한적으로 보입니다. 누락 된 다양한 부분이 있습니다 (예 : 스트림으로 재사용 가능한 스트림 및 옵션). 반면에 Stream API를 구현하는 것은 확실히 API에 큰 변화였습니다. 이유 때문에 여러 번 연기되었습니다. 따라서 Oracle은 가장 중요한 사용 사례로 변경 사항을 제한하고 싶었습니다. 어쨌든 열거 형은 그렇게 많이 사용되지 않습니다. 물론 모든 프로젝트에는 두 가지가 있지만 목록 및 다른 컬렉션의 수에 비하면 아무것도 아닙니다. Enum이있는 경우에도 대부분의 경우 반복하지 않습니다. 반면에 목록과 집합은 거의 매번 반복됩니다. 이것이 Enum이 Stream 세계에 대한 자체 어댑터를 얻지 못한 이유라고 생각합니다. 이 기능이 향후 버전에 추가되는지 여부를 살펴 보겠습니다. 그리고 그때까지 당신은 항상 사용할 수 있습니다Arrays.stream.


나는 갈 것이다 EnumSet. forEach()정의되어 있기 때문에 Iterable스트림 생성을 아예 피할 수 있습니다.

EnumSet.allOf(Letter.class).forEach(x -> foo(x));

또는 메서드 참조 :

EnumSet.allOf(Letter.class).forEach(this::foo);

그래도 oldschool for-loop는 조금 더 간단하다고 느낍니다.

for (Letter x : Letter.values()) {
    foo(x);
}

생각 에 열거 형은 크기가 제한되어 있으므로 (즉, 크기는 언어에 의해 제한되지 않고 사용에 따라 제한됨) 네이티브 스트림 API 가 필요하지 않습니다 . 스트림은 변형을 조작하고 스트림의 요소를 다시 수집해야 할 때 매우 좋습니다. 이는 Enum의 일반적인 사용 사례가 아닙니다 (일반적으로 enum 값을 반복하지만 변환, 매핑 및 수집 할 필요가 거의 없음).

각 요소에 대한 작업 만 수행해야하는 경우에는 forEach 메서드 만 노출해야합니다.

     public static void forEach(Consumer<Letter> action) {
            Arrays.stream(Letter.values()).forEach(action);
     }

     .... //example of usage
     Letter.forEach(e->System.out.println(e));

Stream열거 형 상수 를 얻는 가장 짧은 코드 Stream.of(Letter.values()). 그렇게 좋지는 Letter.values().stream()않지만 특히 열거 형이 아닌 배열의 문제입니다.

또한 열거 형에 stream()메서드 가없는 이유는 무엇입니까?

가능한 가장 좋은 전화가 Letter.stream(). 불행히도 클래스는 동일한 시그니처를 가진 두 개의 메서드를 가질 수 없으므로 stream()모든 열거 형에 정적 메서드 암시 적으로 추가 할 수 없습니다 (모든 열거 형 에 암시 적으로 추가 된 정적 메서드 가있는 것과 동일한 방식 values()). 라는 매개 변수가없는 정적 또는 인스턴스 메소드가 이미 있습니다 stream().

이 접근 방식이 괜찮습니까?

I think so. The drawback is that stream is a static method, so there is no way to avoid code duplication; it would have to be added to every enum separately.

ReferenceURL : https://stackoverflow.com/questions/29922296/java-8-way-to-work-with-an-enum

반응형