객체 배열을 기본 유형의 배열로 변환


80

기본 유형 (예 : Byte, Integer, Char 등)을 가진 Java 객체의 배열이있는 경우. 기본 유형의 배열로 변환 할 수있는 깔끔한 방법이 있습니까? 특히 이것은 새 배열을 만들고 내용을 반복하지 않고도 수행 할 수 있습니다.

예를 들어

Integer[] array

이것을 변환하는 가장 좋은 방법은 무엇입니까

int[] intArray

불행히도 이것은 Hibernate와 우리가 통제 할 수없는 일부 써드 파티 라이브러리 사이에 인터페이스 할 때 우리가 꽤 자주해야하는 일입니다. 이것은 매우 일반적인 작업이 될 것 같아서 지름길이 없다면 놀랄 것입니다.

당신의 도움을 주셔서 감사합니다!

답변:


40

불행히도 Java 플랫폼에는이를 수행하는 것이 없습니다. Btw, 또한 배열의 null요소 를 명시 적으로 처리해야합니다 Integer[](이에 대해 무엇 int을 사용할 예정입니까?).


6
널에 대한 좋은 점. 내 목적을 위해 항목 중 하나가 null이면 예외가 throw되는 것을 수락했을 것입니다. 개체의 상자를 풀 때 NullPointerException이 throw되는 것과 같은 방식입니다.
Il-Bhima

2
이 답변은 Java 8에서 더 이상 정확하지 않습니다 . Alex의 답변을 참조하십시오 .
robinst


70

Java 8에 도입 된 스트림을 사용하면 다음을 수행 할 수 있습니다.

int[] intArray = Arrays.stream(array).mapToInt(Integer::intValue).toArray();

그러나 현재 int, long및에 대한 기본 스트림 만 double있습니다. byte외부 라이브러리없이 가장 짧은 방법 과 같은 다른 기본 유형으로 변환해야하는 경우 다음과 같습니다.

byte[] byteArray = new byte[array.length];
for(int i = 0; i < array.length; i++) byteArray[i] = array[i];

또는 원하는 경우 for 루프를 스트림으로 바꿀 수 있습니다.

IntStream.range(0, array.length).forEach(i -> byteArray[i] = array[i]);

이 모든 NullPointerException요소는 요소 중 하나라도 null.


2
대신 (언 박싱 사용)을 Integer::intValue사용할 수도 있습니다 i -> i.
robinst

1
@robinst 그리고 unboxing은 컴파일러 Integer::intValue가 당신을 부르는 것인데 , 메소드를 쉽게 사용할 수 있는데 왜 새로운 람다를 생성할까요?
Andreas

@Andreas 그냥 다른 옵션을 나열하면 코드 스타일 / 개인 선호도의 문제입니다. 또한 두 가지 접근 방식을 마이크로 벤치 마크 (JMH 사용)했으며 성능이 동일합니다.
robinst

게시 된 첫 번째 코드 스 니펫을 사용하면 "정적 컨텍스트에서 비 정적 메서드를 사용할 수 없습니다."라는 오류가 발생하여 대신 int[] ints = Arrays.stream(objects).mapToInt(i -> Integer.parseInt(i.toString())).toArray(); 했습니다. 동일한 문제가있는 사람에게 도움이되기를 바랍니다. 더 나은 방법을 아는 사람이 있으면 알려주세요.
Kartik Chugh

이것은 오늘날 받아 들여지는 대답이어야합니다. 감사합니다 Alex.
Per Lundberg


3

특히 이것은 새 배열을 만들고 내용을 반복하지 않고도 수행 할 수 있습니다.

Java에서는 Integer 배열을 int로 변환 할 수 없습니다 (즉, 배열 요소의 유형을 변경할 수 없음). 따라서 새 int [] 배열을 만들고 Integer 개체의 값을 여기에 복사하거나 어댑터를 사용할 수 있습니다.

class IntAdapter {
    private Integer[] array;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { return array[index].intValue(); }
}

이렇게하면 코드를 좀 더 읽기 쉽게 만들 수 있으며 IntAdapter 개체는 몇 바이트의 메모리 만 사용합니다. 어댑터의 가장 큰 장점은 여기에서 특수한 경우를 처리 할 수 ​​있다는 것입니다.

class IntAdapter {
    private Integer[] array;
    public int nullValue = 0;
    public IntAdapter (Integer[] array) { this.array = array; }
    public int get (int index) { 
        return array[index] == null ? nullValue : array[index].intValue();
    }
}

또 다른 해결책은 많은 사전 정의 된 어댑터를 포함 하는 Commons Primitives 를 사용 하는 것입니다. 귀하의 경우 ListIntList을 살펴 보십시오 .


2

아니면 한 번만 할 거라면 쉬운 방법으로하세요. 그러나 Integer! = null 케이스에 대해 이야기하지 않았습니다.

    //array is the Integer array
    int[] array2 = new int[array.length];
    int i=0;
    for (Integer integer : array) {
        array2[i] = integer.intValue();
        i++;
    }

1

달러 사용 은 다음과 같이 간단합니다.

Integer[] array = ...;
int[] primitiveArray = $(array).toIntArray();

6
이것은 적어도 Java 1.6 또는 1.7이 아닌 Java로 보이지 않습니다.
Lordalcol 2013-06-20

2
@LorDalCol 달러 실제로 자바 라이브러리입니다
야로슬라프 Záruba

1
Java 메소드의 이름을 지정할 수 있습니다 $! 나는 그것이 비록 권장 생각하지 않습니다 ...
올레 VV
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.