Converting a Collection<br>to an array

5185 단어 프레임sun
원문:http://www.javablogging.com/converting-a-collection-to-an-array/
   자바 5 의 Collections 를 사용 했다 면 Collection < T > 출력 배열 형식 이 T 인 문제 에 어려움 을 겪 을 수 있 습 니 다.Collection Interface 에서 toArray () 를 Object [] 형식 으로 되 돌려 주 는 방법 이 있 습 니 다.그러나 자바 5 의 Collection 이 범 형 을 사용한다 면, array T [] 를 우리 의 Collection < T > 성명 에 사용 하지 말 아야 합 니까?물론 한 가지 방법 이 있 습 니 다. T [] toArray (T [] a).근 데 이 이상 한 'T [] a' 가 어디서 났 어 요?왜 이상 한 인자 가 없 는 간단 한 방법 이 아 닙 니까? T [] toArray (T [] a)?자바 5 에서 이러한 방법 을 실현 하 는 데 큰 문제 가 있어 서 는 안 될 것 같 지만, 사실상 자바 5 에서 할 수 없 는 이 유 를 아래 에서 설명 하 겠 습 니 다.
    우 리 는 이러한 방법 을 스스로 실현 하려 고 시도 하 는 것 부터 시작 합 니 다. 예 를 들 어 우 리 는 Array List 류 를 계승 하여 방법 T [] toArray T () 를 실현 할 수 있 습 니 다.간단 하기 위해 서 우 리 는 Object [] toArray () 방법 을 T [] 로 강제 전환 하여 실현 합 니 다.



import java.util.*;

/**
 * Implementation of the List interface with "T[] toArrayT()" method.
 * In a normal situation you should never extend ArrayList like this !
 * We are doing it here only for the sake of simplicity.
 * @param <T> Type of stored data
 */
class HasToArrayT<T> extends ArrayList<T> {
    public T[] toArrayT() {
        return (T[]) toArray();
    }
}

public class Main {
    public static void main(String[] args) {
        // We create an instance of our class and add an Integer
        HasToArrayT<Integer> list = new HasToArrayT<Integer>();
        list.add(new Integer(4));

        // We have no problems using the Object[] toArray method
        Object[] array = list.toArray();
        System.out.println(array[0]);

        // Here we try to use our new method... but fail on runtime
        Integer[] arrayT = list.toArrayT(); // Exception is thrown :
        // "Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer"
        System.out.println(arrayT[0]);
    }
}

   만약 당신 이 이 코드 를 컴 파일 한다 면, 우리 가 이 새로운 방법 을 사용 하려 고 시도 할 때, 그것 은 exception 을 던 질 것 입 니 다.근 데 왜 요?근 데 왜?우리 가 잘 못 했 나?저장 소 는 Integers 와 toArray 방법 으로 돌아 오 는 Objects 배열 이기 때문에 이것 이 문제 입 니 다.
    자바 컴 파일 러 는 우리 의 잘못 을 이해 하기 위해 힌트 를 주 었 다.컴 파일 을 통 해 11 번 째 줄 의 warning 을 볼 수 있 습 니 다. "Type Safety" 라 고 말 합 니 다.Unchecked cast 는 Object [] 에서 T [] 까지 이 문 제 를 따라 이 array 가 방법 toArray T () 에서 돌아 오 는 진정한 유형 이 Integer [] 인지 확인 하고 아래 코드 를 main () 에 두 십시오.
이전:
Integer[] arrayT = list.toArrayT()

    이 프로그램 을 실행 할 때 "false" 를 받 아야 합 니 다. 이것 은 toArray T () 가 돌아 온 것 을 의미 합 니 다.
Integer [] 가 아 닙 니 다. 왜 죠?많은 사람들 이 답 을 알 고 있 을 지도 모른다. 이것 이 바로 Type Erasure 다.기본적으로 컴 파일 러 는 컴 파일 과정 에서 범 형 에 관 한 모든 유형 을 제거 합 니 다.프로그램 이 실 행 될 때 모든 T 가 HasToArray T 클래스 에 있 는 이미 지 는 간단 한 대상 이 아 닙 니 다.이 는 방법 toArray T 가 Integer [] 로 전환 되 지 않 았 음 을 의미 하 며, 일반적인 형식 에서 Integer 로 정의 되 더 라 도.사실 여기 에는 두 번 째 문제 가 있 습 니 다. 자바 에서 배열 전환 을 처리 하 는 방식 입 니 다.지금 우 리 는 단지 첫 번 째 문제 인 범 형의 사용 에 집중 하고 싶 을 뿐이다.
    그래서 만약 에 T 대표 Integer 가 운행 기간 에 지 워 진다 면 진정한 array of type Integer [] 로 돌아 갈 방법 이 없 을까요?물론 가능 하고 이미 존재 하 는 방법 T [] toArray (T [] a) 는 Collections 프레임 워 크 에서 바로 이 역할 을 합 니 다.그러나 대 가 는 자신 이 만 든 매개 변수 인 스 턴 스 를 추가 하 는 것 이다.어떻게 사용 하나 요?어떻게 이 루어 졌 는 지 볼 까요?예 를 들 어 Array List 의 실현:

    System.out.println("toArrayT() returns Integer[] : "
    + (list.toArrayT() instanceof Integer[]));

    javadoc 의 이 방법 에 따 르 면 이 배열 a 가 elements 를 만족 시 킬 수 있 는 공간 이 충분 하 다 면 이 배열 에 충분 한 공간 이 없 으 면 새로운 배열 을 만 들 것 입 니 다.이 를 통 해 Arrays. copy Of 방법 으로 새 배열 을 만 들 고 a. getClass () 를 통 해 배열 을 만 들 형식 을 지정 하 는 것 을 보 았 습 니 다.
이것 이 바로 인자 가 필요 한 이유 입 니 다. 배열 을 만 들 유형 을 알 기 위해 서 입 니 다.그리고 a. getClass () 대신 T. class 를 통 해 더 쉬 워 보이 지 않 을 까?아니!type erasure 때문에 T 는 우리 가 지정 한 유형 이 아 닙 니 다.그리고 우리 가 T. class 를 사용 하면 컴 파일 러 오 류 를 얻 을 수 있 습 니 다!새로운 배열 을 만 드 는 간단 한 방법 인 new T [] 를 생각 할 지 모 르 지만 같은 이유 로 불가능 합 니 다.
    직접적 으로 말 하면 진정 으로 지정 한 형식의 array of T 를 되 돌리 기 위해 서 는 함수 toArray 에 해당 하 는 유형 을 제공 해 야 합 니 다.함수 에서 만 든 배열 형식 을 제공 할 수 있 는 다른 방법 은 없습니다. 범 형 T 는 Collection 실행 기 에 만 들 때 취소 되 었 기 때 문 입 니 다.
    또 다른 경 로 는 Class < T [] > 입력 매개 변 수 를 전달 하여 이 함 수 를 실현 하 는 것 입 니 다. 이 방식 은 toArray (a) 의 a 를 대체 하 는 새로운 배열 T [] 를 만 드 는 것 입 니 다. 우 리 는. class 도 메 인 - toArray T (TYPE []. class) 를 사용 할 수 있 습 니 다.

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

    그것 은 여전히 하나의 인자 가 필요 하지만, 이것 은 T [] toArray (T [] a) 함수 에 두 가지 장점 이 있다.우선, 그것 은 다른 흔히 볼 수 있 는 배열 이 아니 라 전 달 된 인 스 턴 스 를 직접 사용 할 필요 가 없다.둘째, 그것 은 간단 하 다. 물론 그것 의 확정 도 하나의 입력 매개 변수 가 있다.
    한 마디 로 완벽 한 해결 방법 이 없다 면 가장 좋 은 해결 방법 은 배열 을 사용 하지 않 는 것 이다.배열 코드 는 제어 하기 어렵 고 실 수 를 하 며 실 행 될 때 나타 납 니 다.만약 당신 이 collections 를 자주 사용 하고 익숙 하 다 면, toArray 에 주의 하 는 방법 을 피 할 수 없 을 것 입 니 다.

좋은 웹페이지 즐겨찾기