배열에서 스트리밍 할 때 정수를 문자열에 매핑 할 수없는 이유는 무엇입니까?


94

이 코드는 작동합니다 (Javadoc에서 가져옴).

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
String commaSeparatedNumbers = numbers.stream()
    .map(i -> i.toString())
    .collect(Collectors.joining(", "));

이것은 컴파일 할 수 없습니다.

int[] numbers = {1, 2, 3, 4};
String commaSeparatedNumbers = Arrays.stream(numbers)
    .map((Integer i) -> i.toString())
    .collect(Collectors.joining(", "));

IDEA는 "람다 식에 호환되지 않는 반환 유형 문자열"이 있다고 말합니다.

왜 ? 그리고 그것을 고치는 방법?

답변:


120

Arrays.stream(int[])IntStream아니라 Stream<Integer>. 따라서를 객체에 매핑 할 때 mapToObj대신 을 호출해야 합니다.mapint

예상대로 작동합니다.

String commaSeparatedNumbers = Arrays.stream(numbers)
    .mapToObj(i -> ((Integer) i).toString()) //i is an int, not an Integer
    .collect(Collectors.joining(", "));

다음과 같이 작성할 수도 있습니다.

String commaSeparatedNumbers = Arrays.stream(numbers)
    .mapToObj(Integer::toString)
    .collect(Collectors.joining(", "));

3
IntStream과 의 차이점은 무엇입니까 Stream<Integer>?
Florian Margaine 2015 년

8
@FlorianMargaine An IntStream은 원시 int값에 대한 스트림 전문화입니다 . A Stream<Integer>Integer개체를 보유한 스트림 입니다.
Alexis C.

2
@FlorianMargaine IntStream은 스트림 또는 기본 요소 (ints) 인 반면 Steram<Integer>객체 스트림입니다. 원시 스트림에는 성능상의 이유로 특수한 방법이 있습니다.
assylias

7
IntStream.mapToObjIntFunction을 소비하는 함수 인을 기대 int하므로  .mapToObj((Integer i) -> i.toString())작동하지 않습니다. 에서 int로의 불필요한 변환이 포함되어 있으므로 권장하지 않습니다 Integer. 반대로, 메서드 .mapToObj(Integer::toString)를 호출하므로 훌륭하게 작동합니다 . 이것은 모호하기 때문에 후자가 컴파일되지 않기 때문에 호출 하는  것과 다릅니다 . staticInteger.toString(int).map(Integer::toString)Stream<Integer>
Holger 2015 년

1
@cic : 아니, 호출 .map(Integer::toString)A의 것은 Stream<Integer>모두 참으로 모호하지, .map(i->i.toString())그리고 .map(i->Integer.toString(i))유효합니다. 그러나을 사용하면 쉽게 해결할 수 있습니다 .map(Object::toString).
홀거

19

Arrays.stream(numbers)를 생성 IntStream후드와의지도 동작 IntStream요구 IntUnaryOperator(즉, 기능 int -> int). 적용하려는 매핑 기능이이 계약을 따르지 않으므로 컴파일 오류가 발생합니다.

(이것이 반환됩니다) boxed()를 얻으려면 전에 전화해야합니다 . 그런 다음 첫 번째 스 니펫에서 한 것처럼 호출 하십시오.Stream<Integer>Arrays.asList(...).stream()map

주 당신이 필요로하는 경우 그 boxed()다음에 map당신은 아마 사용하고자하는 mapToObj직접.

장점은 개체에 mapToObjint값을 상자에 넣을 필요가 없다는 Integer것입니다. 물론 적용하는 매핑 기능에 따라 그래서이 옵션은 쓰기도 더 짧습니다.


5

Arrays.stream (int [])을 사용하여 정수 스트림을 만들 수 있으며 다음 mapToObj과 같이 호출 할 수 있습니다 mapToObj(Integer::toString).

String csn = Arrays.stream(numbers) // your numbers array
.mapToObj(Integer::toString)
.collect(Collectors.joining(", "));

도움이 되었기를 바랍니다..


2

권투, AFAIK 및 힙에 추가 된 작은 문자열 폭발 없음 :

public static void main(String[] args) {
    IntStream stream = IntStream.of(1, 2, 3, 4, 5, 6);
    String s = stream.collect(StringBuilder::new, (builder, n) -> builder.append(',').append(n), (x, y) -> x.append(',').append(y)).substring(1);
    System.out.println(s);
}

1

이 샘플 및 질문의 목적이 문자열을 int 스트림에 매핑하는 방법을 찾는 것이라면 (예 : int 스트림을 사용하여 문자열 배열의 인덱스에 액세스) boxing을 사용하고 다음으로 캐스팅 할 수도 있습니다. int (그러면 배열의 인덱스에 액세스 할 수 있음).

int[] numbers = {0, 1, 2, 3}; 
String commaSeparatedNumbers = Arrays.stream(numbers)
    .boxed()
    .map((Integer i) -> Integer.toString((int)i))
    .collect(Collectors.joining(", "));

.boxed () 호출은 IntStream (기본 int 스트림)을 Stream (객체 스트림, 즉 Integer 객체)으로 변환하여 다음에서 객체 (이 경우 String 객체)의 반환을 수락합니다. 당신의 람다. 여기에서는 데모 목적으로 숫자의 문자열 표현 일 뿐이지 만, 이전에 언급 한 문자열 배열의 요소와 같이 모든 문자열 객체가 될 수 있습니다.

또 다른 가능성을 제시하겠다고 생각했습니다. 프로그래밍에는 항상 작업을 수행하는 여러 가지 방법이 있습니다. 가능한 한 많이 알고 나서 성능 문제, 직관성, 코드의 명확성, 선호하는 코딩 스타일 및 가장 자체 문서화를 염두에두고 현재 작업에 가장 적합한 것을 선택하십시오.

즐거운 코딩 되세요!


1
당신은 불필요한 일을하고 있습니다. 각각 int의 래퍼 유형으로 상자 를 만들고 Integer직후에 상자 를 풉니 다.
Alexis C.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.