Java :지도 기능이 있습니까?


140

지도 기능이 필요 합니다. Java에 이미 이와 같은 것이 있습니까?

(궁금한 사람들을 위해 : 물론이 사소한 기능을 직접 구현하는 방법을 알고 있습니다 ...)


1
그렇지 않다면 자신을 정의하는 것이 쉽지 않습니다. 그러나 Google이 12 가지 구현을 알고 있다고 가정합니다.


6
@ 크리스 : 어떻게 같은 질문입니까?
Albert

1
이 질문에 대한 대답이 예이면 다른 연결된 질문에도 대답합니다. 대답이 '아니오'인 경우에는 전혀 관련이 없습니다.
Albert

1
Java8로,이 @delnan가 언급되었을 수 있습니다 무엇 leveluplunch.com/java/examples/...
Eternalcode

답변:


86

Java 6에서 JDK에는 함수에 대한 개념이 없습니다.

구아바 에는 기능 인터페이스가 있지만이 방법은 필요한 기능을 제공합니다.
Collections2.transform(Collection<E>, Function<E,E2>)

예:

// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
    Collections2.transform(input, new Function<Integer, String>(){

        @Override
        public String apply(final Integer input){
            return Integer.toHexString(input.intValue());
        }
    });
System.out.println(output);

산출:

[a, 14, 1e, 28, 32]

요즘 Java 8에는 실제로지도 기능이 있으므로 코드를보다 간결하게 작성합니다.

Collection<String> hex = input.stream()
                              .map(Integer::toHexString)
                              .collect(Collectors::toList);

8
Guava를 사용하면 작업을 수행 할 수 있지만 code.google.com/p/guava-libraries/wiki/FunctionalExplained ( "주의 사항"섹션 읽기)를 원하지 않을 수도 있습니다 .
Adam Parkin

2
@AdamParkin true, 그러나 이것은 이것보다 더 고급 기능 개념을 참조한다고 확신합니다. 그렇지 않으면 처음 에는 transform ( ) 메소드를 개발하지 않았을 것입니다
Sean Patrick Floyd

2
실제로, 아닙니다. 기능적인 관용구로 인해 성능이 현저하게 저하되는 경우가 종종 있습니다. 따라서 두 가지 기준을 모두 충족한다고 확신하는 경우에만 시설을 사용해야한다고 강조합니다. 코드베이스에 대한 전체 LOC 절감 및 입증 게으른 평가로 인한 성능 향상 (또는 최소한 성능 저하). 그것들의 사용에 대해 논쟁하지 않고 단지 당신이 가고 있다면 구현 자의 경고에 유의해야 함을 나타냅니다.
Adam Parkin

4
@SeanPatrickFloyd 이제 Java 8이 종료되었으므로 람다와 관련된 예제로 이것을 업데이트하고 싶습니까? 마찬가지로Collections2.transform(input -> Integer.toHexString(intput.intValue())
다니엘 Lubarov

2
@Daniel Java 8에서는 Guava와 함께 할 이유가 없습니다. 대신 나는 leventov의 대답을 위해 갔다
Sean Patrick Floyd

92

Java 8부터 JDK에서이를 수행하는 몇 가지 표준 옵션이 있습니다.

Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());

참조 java.util.Collection.stream()java.util.stream.Collectors.toList().


140
이것은 너무나 장황해서 내 안에 상처를줍니다.
Natix

1
@Natix는에 동의합니다 toList(). 다른 유형으로 교체 :(List<R>)((List) list).replaceAll(o -> doMap((E) o));
leventov

2
e -> doMap(e)그냥 대체 할 수 있습니까 doMap?
jameshfisher

3
@jameshfisher, 그래, 같은 foo::doMapFoo::doMap.
leventov

9
이것이 스칼라가 존재하는 이유라고 생각합니다. Java 12가 읽을 수있게 될 때까지 기다리십시오.
JulienD

26

Java가 갖고 싶어하는 많은 것들을 처리하는 Functional Java 라는 훌륭한 라이브러리 가 있지만 그렇지 않습니다. 다시 말하지만 Java 가해 야 할 모든 것을 수행하지만 여전히 JVM 용으로 작성된 것과 호환되지 않는이 멋진 언어 스칼라가 있습니다.


나는 그들이 다음 구문을 어떻게 활성화 시켰는가에 관심이있다 : a.map({int i => i + 42});그들은 컴파일러를 확장 했습니까? 또는 추가 전 처리기?
Andrey

@Andrey-직접 요청하거나 소스 코드를 확인하여 수행 방법을 확인할 수 있습니다. 다음은 소스에 대한 링크입니다. functionaljava.org/source
wheaties

1
@Andrey : 예제는 BGGA 클로저 제안의 구문을 사용합니다. 실행중인 프로토 타입이 있지만 아직 '공식'Java에는 없습니다.
Peter Štibraný

@Andrey :이 구문은 Java 클로저에 대해 제안 된 사양의 일부입니다 (홈페이지의 마지막 두 번째 단락 참조). 프로토 타입 구현 만 있습니다.
Michael Borgwardt

2
Scala thread hijack :( 그래서 JavaPosse 메일 링리스트처럼되지 않기를 바란다)
Jorn

9

Collections2.transform()구아바를 조심하십시오 . 이 방법의 가장 큰 장점은 게으름이라는 가장 큰 위험입니다.

의 문서 Lists.transform()를 참조하십시오 Collections2.transform().

이 함수는 느리게 적용되며 필요할 때 호출됩니다. 이것은 돌려 주어진리스트가 뷰가되기 위해서 필요 합니다만, 이것은 List.contains (java.lang.Object) 및 List.hashCode ()와 같은 벌크 오퍼레이션에 함수가 여러번 적용되는 것을 의미합니다. 이것이 잘 수행 되려면 기능이 빨라야합니다. 리턴 된 목록이보기 일 필요가 없을 때 지연 평가를 피하려면 리턴 된 목록을 선택한 새 목록으로 복사하십시오.

또한 문서 Collections2.transform()에서 라이브 뷰를 얻는다고 언급했는데 소스 목록의 변경 사항은 변환 된 목록에 영향을 미칩니다. 개발자가 작동 방식을 모르는 경우 이런 종류의 동작으로 인해 추적하기 어려운 문제가 발생할 수 있습니다.

더 고전적인 "지도"를 원한다면 한 번만 실행 FluentIterable되며 구아바에서도 훨씬 더 간단한 작업을 수행하는 것이 좋습니다. 다음은 Google 예제입니다.

FluentIterable
       .from(database.getClientList())
       .filter(activeInLastMonth())
       .transform(Functions.toStringFunction())
       .limit(10)
       .toList();

transform()지도 방법은 다음과 같습니다. 와 동일한 Function <> "콜백"을 사용 Collections.transform()합니다. 당신이 얻는 목록은 읽기 전용이지만 copyInto()읽기-쓰기 목록을 얻는 데 사용 하십시오.

그렇지 않으면 물론 java8이 람다와 함께 나올 때 이것은 쓸모가 없습니다.



2

오래된 질문이지만 다른 해결책을 제시하고 싶습니다.

Java 제네릭과 Java 8 스트림을 사용하여 자신의 작업을 정의하십시오.

public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
   return collection.stream().map(mapFunction).collect(Collectors.toList());
}

다음과 같은 코드를 작성할 수있는 것보다 :

List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.