Java에서 int []를 Integer []로 변환하는 방법?


167

나는 Java를 처음 접했고 매우 혼란 스러웠다.

길이가 4 인 큰 데이터 세트가 int[]있으며 4 개의 정수의 각 특정 조합이 발생하는 횟수를 계산하고 싶습니다. 이것은 문서에서 단어 빈도를 계산하는 것과 매우 유사합니다.

Map<int[], double>목록이 반복 될 때 각 int []를 실행 횟수에 매핑 하는을 만들고 싶지만 Map은 기본 유형을 사용하지 않습니다.

그래서 나는 만들었다 Map<Integer[], Double>

내 데이터는 저장되어 ArrayList<int[]>있으므로 루프는

ArrayList<int[]> data = ... // load a dataset`

Map<Integer[], Double> frequencies = new HashMap<Integer[], Double>();

for(int[] q : data) {

    // **DO SOMETHING TO convert q from int[] to Integer[] so I can put it in the map

    if(frequencies.containsKey(q)) {
    frequencies.put(q, tfs.get(q) + p);
    } else {
        frequencies.put(q, p);
    }
}

나는 확실히 내가 변환이 작동하도록 주석에 필요한 코드가 아니에요 int[]에를 Integer[]. 아니면 올바른 방법으로 근본적으로 혼란 스러울 수 있습니다.


6
"Map <int [], double> ...을 만들고 싶지만 Map은 기본 유형을 사용하지 않습니다." 아래 게시물 중 하나에서 지적했듯이 int []는 기본 유형이 아니므로 실제 문제는 아닙니다. 실제 문제는 배열이 요소를 비교하기 위해 .equals ()를 재정의하지 않는다는 것입니다. 그런 의미에서 Integer []로 변환하는 것은 (제목에서 알 수 있듯이) 도움이되지 않습니다. 위의 코드에서 frequency.containsKey (q)는 .equals ()를 사용하여 비교하기 때문에 여전히 예상대로 작동하지 않습니다. 실제 해결책은 여기서 배열을 사용하지 않는 것입니다.
newacct

다른 답변으로 스팸 메일을 보내고 싶지는 않지만 이제 이에 대한 문서 예제 가 있습니다.
Mureinik

답변:


189

기본 Java 8 (한 줄)

Java 8을 사용하면 다음과 같이 쉽게 int[]변환 할 Integer[]수 있습니다.

int[] data = {1,2,3,4,5,6,7,8,9,10};

// To boxed array
Integer[] what = Arrays.stream( data ).boxed().toArray( Integer[]::new );
Integer[] ever = IntStream.of( data ).boxed().toArray( Integer[]::new );

// To boxed list
List<Integer> you  = Arrays.stream( data ).boxed().collect( Collectors.toList() );
List<Integer> like = IntStream.of( data ).boxed().collect( Collectors.toList() );

다른 사람들이 언급했듯이 Integer[]일반적으로 좋은 맵 키는 아닙니다. 그러나 변환이 진행되는 한, 우리는 이제 비교적 깨끗하고 원시적 인 코드를 가지고 있습니다.


3
한편 올바른 방법입니다. 정수형 배열이 목록으로 필요하면 다음과 같이 작성할 수 있습니다.List<Integer> list = IntStream.of(q).boxed().collect(Collectors.toList());
aw-think

로 변환하려면 Integer[]실제로 다음 구문을 사용하는 것이 좋습니다. Integer[] boxed = IntStream.of(unboxed).boxed().toArray();@NwDx와 비슷한 방식으로
YoYo

1
@JoD. 그렇습니다. 그러나 어쨌든 IntStream.of전화 Arrays.stream합니다. 나는 그것이 개인적 선호에 달려 있다고 생각합니다-나는 하나의 재정의 된 기능을 선호합니다.
Sheepy

2
그것은 미쳤지 만 훌륭한 해결책입니다! 감사합니다!
Rugal

1
@VijayChavda 메소드 참조 라고하는 새로운 구문 은 2014 년에 람다 ( JSR 335 Part C )의 일부로 Java 8과 함께 도입되었습니다 . 의미 the "new" method (constructor) of the Integer[] class합니다.
Sheepy

79

당신이를 변환 할 경우 int[]Integer[]는 JDK에서 할 수있는 자동화 된 방법은 없습니다 있습니다. 그러나 다음과 같이 할 수 있습니다.

int[] oldArray;

... // Here you would assign and fill oldArray

Integer[] newArray = new Integer[oldArray.length];
int i = 0;
for (int value : oldArray) {
    newArray[i++] = Integer.valueOf(value);
}

Apache lang 라이브러리에 액세스 할 수 있으면 다음 ArrayUtils.toObject(int[])과 같은 방법을 사용할 수 있습니다 .

Integer[] newArray = ArrayUtils.toObject(oldArray);

71
그것은 for 루프를 수행하는 불쾌한 방법입니다.
James Becwar

9
이것은 각각에 대해 완전히 정상입니다 ... 나는 불쾌한 부분을 보지 못합니다.
Dahaka

18
@Dahaka, value색인 변수 i가있는 동안 반복자 가 사용되었습니다.
lcn

1
@Icn, 나는 왜 어떤 사람들이 그 스타일을 선호하지 않는지 알 수 있지만 왜 그렇게 불쾌한 것이 바람직하지 않습니까?
Eddie

14
@icn, @Dahaka : 문제는 이미 증가하는 인덱스 변수를 사용하고 있기 때문에 for-each도 사용할 필요가 없다는 것입니다. 코드에서는 예쁘고 단순 해 보이지만 불필요한 오버 헤드가 발생하는 비하인드 스토리. 전통적인 for (int i...)루프가 더 효율적입니다.
daiscog

8

아마도지도의 키가 배열의 정체성 대신 요소의 값과 일치하기를 원할 것입니다. 이 경우 원하는 대로 정의 equals하고 정의하는 객체가 필요합니다 hashCode. 가장 쉬운은로 변환하는 것입니다 List<Integer>어느 쪽, ArrayList또는 더 나은 사용 Arrays.asList. 그보다 데이터를 나타내는 클래스를 도입 할 수 있습니다 (유사 java.awt.Rectangle하지만 변수를 private final로 만들고 클래스를 final로 만드는 것이 좋습니다).


: 아, 여기 배열 변환 질문, 주변 단지 다른 방법 stackoverflow.com/questions/564392/...
톰 Hawtin의 - tackline

8

외부 라이브러리없이 일반 for-loop 사용 :

int []를 정수 []로 변환 :

int[] primitiveArray = {1, 2, 3, 4, 5};
Integer[] objectArray = new Integer[primitiveArray.length];

for(int ctr = 0; ctr < primitiveArray.length; ctr++) {
    objectArray[ctr] = Integer.valueOf(primitiveArray[ctr]); // returns Integer value
}

정수 []를 int []로 변환 :

Integer[] objectArray = {1, 2, 3, 4, 5};
int[] primitiveArray = new int[objectArray.length];

for(int ctr = 0; ctr < objectArray.length; ctr++) {
    primitiveArray[ctr] = objectArray[ctr].intValue(); // returns int value
}

6

나는 이전 답변에서 틀렸다. 올바른 해결책은이 클래스를지도에서 실제 int []를 감싸는 키로 사용하는 것입니다.

public class IntArrayWrapper {
        int[] data;

        public IntArrayWrapper(int[] data) {
            this.data = data;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            IntArrayWrapper that = (IntArrayWrapper) o;

            if (!Arrays.equals(data, that.data)) return false;

            return true;
        }

        @Override
        public int hashCode() {
            return data != null ? Arrays.hashCode(data) : 0;
        }
    }

다음과 같이 코드를 변경하십시오.

   Map<IntArrayWrapper, Double > freqs = new HashMap<IntArrayWrapper, Double>();

    for (int[] data : datas) {
        IntArrayWrapper wrapper = new IntArrayWrapper(data);

        if ( freqs.containsKey(wrapper)) {
            freqs.put(wrapper, freqs.get(wrapper) + p);
        }

        freqs.put(wrapper, p);
    }

1
나는 수업을 최종으로 만들고 필드를 비공개로 만듭니다. 생성자 (복제)에서 배열의 방어 복사본을 만듭니다. 그리고 특별한 if 문이 아닌 Arrays.equals에서 값을 반환하십시오. toString이 좋을 것입니다.
Tom Hawtin-tackline

1
아, null 데이터에 대한 생성자 (아마도 clone 호출)에서 NPE를 throw하고 hashCode를 확인하지 마십시오.
Tom Hawtin-tackline

True .. 그러나 동일 코드 인 hashCode는 IDEA :-)에 의해 생성됩니다. 제대로 작동합니다.
Mihai Toader

6
  1. int []를 정수 []로 변환

    public static Integer[] toConvertInteger(int[] ids) {
    
      Integer[] newArray = new Integer[ids.length];
         for (int i = 0; i < ids.length; i++) {
           newArray[i] = Integer.valueOf(ids[i]);
         }
       return newArray;
    }
  2. 정수 []를 int []로 변환

    public static int[] toint(Integer[] WrapperArray) {
    
       int[] newArray = new int[WrapperArray.length];
          for (int i = 0; i < WrapperArray.length; i++) {
             newArray[i] = WrapperArray[i].intValue();
          }
       return newArray;
    }

2
오토 박싱으로 인해 다소 부정확합니다. 1 예에서 간단히 할 수있는 newArray[i] = ids[i];, 2 하나 newArray[i] = WrapperArray[i]:
장어 리

3

자체 코드를 작성하는 대신 IntBuffer를 사용하여 데이터를 Integer 배열에 복사하지 않고도 기존 int []를 래핑 할 수 있습니다.

int[] a = {1,2,3,4};
IntBuffer b = IntBuffer.wrap(a);

IntBuffer는 비슷한 코드를 구현하므로 이미 작성한 코드를 사용할 수 있습니다. 공식적으로 맵은 키를 비교하여 a.equals (b)를 사용하여 두 개의 키가 동일하다고 가정하므로 배열이 서로 다른 메모리 위치에 있더라도 배열 1,2,3을 가진 두 개의 IntBuffers는 동일하다고합니다. 주파수 코드를 위해 작동하십시오.

ArrayList<int[]> data = ... // load a dataset`

Map<IntBuffer, Double> frequencies = new HashMap<IntBuffer, Double>();

for(int[] a : data) {

    IntBuffer q = IntBuffer.wrap(a);

    if(frequencies.containsKey(q)) {
        frequencies.put(q, tfs.get(q) + p);
    } else {
        frequencies.put(q, p);
    }

}

희망이 도움이


2

왜지도에 Double이 필요한지 잘 모르겠습니다. 당신이하려는 일과 관련하여 int []가 있고 각 시퀀스가 ​​몇 번이나 발생하는지 세고 싶습니까? 어쨌든 더블이 필요한 이유는 무엇입니까?

내가 할 일은 int [] 객체 자체가 이러한 메소드 버전의 데이터를 고려하지 않는다는 사실을 설명하기 위해 적절한 .equals 및 .hashCode 메소드를 사용하여 int 배열에 대한 래퍼를 만드는 것입니다.

public class IntArrayWrapper {
    private int values[];

    public IntArrayWrapper(int[] values) {
        super();
        this.values = values;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + Arrays.hashCode(values);
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        IntArrayWrapper other = (IntArrayWrapper) obj;
        if (!Arrays.equals(values, other.values))
            return false;
        return true;
    }

}

그런 다음 입력 한 요소 유형에 적절한 .equals 및 .hashCode 메소드가있는 한 발생을 계산하기위한 google guava의 다중 세트를 사용하십시오.

List<int[]> list = ...;
HashMultiset<IntArrayWrapper> multiset = HashMultiset.create();
for (int values[] : list) {
    multiset.add(new IntArrayWrapper(values));
}

그런 다음 특정 조합에 대한 개수를 얻으려면

int cnt = multiset.count(new IntArrayWrapper(new int[] { 0, 1, 2, 3 }));

이것은 IntArrayWrapper확실히 사용하기위한 올바른 접근 방식이다 int[]해시 키와 배열을하지만, 이러한 유형이 있음을 언급한다 이미 당신은 그것을 사용할 수 있습니다 ... 배열을 포장 하고뿐만 아니라 그것을 가지고 hashCodeequals그것도 비교입니다.
Holger

2

업데이트 : 아래는 컴파일되지만 ArrayStoreException런타임 에을 던집니다 . 너무 나쁘다. 나중에 참조 할 수 있도록하겠습니다.


변환 int[]Integer[]:

int[] old;
...
Integer[] arr = new Integer[old.length];
System.arraycopy(old, 0, arr, 0, old.length);

나는 System.arraycopy저수준과 모든 것을 감안할 때 이것이 컴파일 되는 것에 약간 놀랐다는 것을 인정해야 하지만, 그렇지 않습니다. 적어도 java7에서는.

다른 방법으로 쉽게 변환 할 수 있습니다.


2
작동하지 않을 때이 답변을 "참조 용으로"유지하는 데 큰 가치가 없습니다. System.arraycopy ()에 대한 문서 에서도이 목적으로 작동하지 않는다고 명시합니다.
Zero3

2

이것은 매력처럼 작동했습니다!

int[] mInt = new int[10];
Integer[] mInteger = new Integer[mInt.length];

List<Integer> wrapper = new AbstractList<Integer>() {
    @Override
    public int size() {
        return mInt.length;
    }

    @Override
    public Integer get(int i) {
        return mInt[i];
    }
};

wrapper.toArray(mInteger);

안녕하세요 Tunaki, 위 코드를 설명해 주시겠습니까? 디버거를 실행할 때 get 및 size 메서드가 자동으로 호출됩니다. 즉, 명시 적으로 호출되지 않습니다. 어떻게 요?! 설명해 주시겠습니까?
forkdbloke 5

0

int []를 정수 []로 변환 :

    import java.util.Arrays;
    ...

    int[] aint = {1,2,3,4,5,6,7,8,9,10};
    Integer[] aInt = new Integer[aint.length];

    Arrays.setAll(aInt, i -> aint[i]);

-1

당신은 필요하지 않습니다. int[]은 객체이며지도 내에서 키로 사용할 수 있습니다.

Map<int[], Double> frequencies = new HashMap<int[], Double>();

주파수 맵의 올바른 정의입니다.

이것은 잘못되었습니다 :-). 적절한 해결책도 게시되어 있습니다 :-).


답장을 보내 주셔서 감사합니다.이를 먼저 시도해 보았지만 제대로 컴파일되었지만 동일한 배열을 두 번 사용 frequencies.containsKey(q)하더라도 항상 거짓 인 것처럼 보입니다. put여기서 int []와의 java 정의 정의와 관련된 결함이 있습니까?

1
(힌트, (new int [0]). equals (new int [0])는 false입니다. (new ArrayList <Integer> ()). equals (new ArrayList <String> ())이 참
Tom Hawtin-tackline

1
배열 비교는 참조 평등을 기반으로하므로 잘못된 생각 입니다. 를 Arrays.equals ()가 존재하는 이유는 ...이다
sleske

제길 :-). 나는 내가 옳기를 바라고 있었다. 선언은 정확하지만 참조 평등 문제로 인해 의미가 잘못되었습니다.
Mihai Toader

-3

간단히 사용하십시오 :

public static int[] intArrayToIntegerArray(int[] a) {
    Integer[] b = new Integer[a.length];
    for(int i = 0; i < array.length; i++){
        b[i] = a[i];
    }
    return g;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.