자바 통합 배열 의 두 가지 실현 방식

10346 단어 Java
최근 에 코드 를 쓸 때 두 개의 배열 을 합병 해 야 한 다 는 수 요 를 만 났 는데 갑자기 예전 에 사용 하지 않 았 다 는 것 을 발견 하고 배열 을 합병 하 는 방식 을 연구 한 결과 다음 과 같다.
1. System. arraycopy () 방법
(1) 해석 은 JDK 소스 코드 를 읽 으 면 다음 과 같은 방법 을 알 수 있 습 니 다.
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

그 중에서 src 는 원본 배열 srcPos 는 원본 배열 복사 의 시작 위치 dest 는 대상 배열 destPos 는 대상 배열 이 복사 데 이 터 를 받 는 시작 위치 length 는 복사 길이 (원본 배열 에서 복사 시작 위치 srcPos 부터 복사 해 야 할 길이) 입 니 다.
이 방법 은 로 컬 방법 임 을 알 수 있 습 니 다. 우 리 는 그 원 리 를 더 깊이 이해 할 수 없습니다. 그러나 우 리 는 그 역할 이 소스 배열 을 시작 위치 srcPos 부터 length 길이 의 요 소 를 목표 배열 로 복사 하 는 것 임 을 알 수 있 습 니 다. 목표 배열 은 destPos 위치 에서 복사 요 소 를 받 기 시작 합 니 다.
(2) 예시
String[] aa = {"11","22","33"};
String[] bb = {"44","55","66"};
String[] cc = {"77","88","99"};

//       
String[] dd = new String[aa.length + bb.length];
System.arraycopy(aa, 0, dd, 0, aa.length);
System.arraycopy(bb, 0, dd, aa.length, bb.length);

//       
String[] ee = new String[aa.length + bb.length + cc.length];
System.arraycopy(aa, 0, ee, 0, aa.length);
System.arraycopy(bb, 0, ee, aa.length, bb.length);
System.arraycopy(cc, 0, ee, aa.length + bb.length, cc.length);

2. ArrayUtils. addAll () 방법
(1) ArrayUtils 도구 류 가 apache comons - lang 3 - 3.5 의 comons - lang 3 - 3.5. jar (jar 패키지 다운로드 주소) 에 있 는 것 을 분석 하기 때문에 사용 하기 전에 이 가방 을 가 져 와 야 합 니 다.그 소스 코드 를 읽 어 보면 알 수 있 듯 이 addAll () 방법 은 본질 적 으로 System. array copy () 방법 을 호출 하 는 것 이다.
public static  T[] addAll(final T[] array1, final T... array2) {
     if (array1 == null) {
         return clone(array2);
     } else if (array2 == null) {
         return clone(array1);
     }
     final Class> type1 = array1.getClass().getComponentType();
     @SuppressWarnings("unchecked") // OK, because array is of type T
     final
     // a 
     T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
     System.arraycopy(array1, 0, joinedArray, 0, array1.length);
     try {
         // b 
         System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
     } catch (final ArrayStoreException ase) {
         // Check if problem was due to incompatible types
         /*
          * We do this here, rather than before the copy because:
          * - it would be a wasted check most of the time
          * - safer, in case check turns out to be too strict
          */
         final Class> type2 = array2.getClass().getComponentType();
         if (!type1.isAssignableFrom(type2)) {
             throw new IllegalArgumentException("Cannot store " + type2.getName() + " in an array of "
                     + type1.getName(), ase);
         }
         throw ase; // No, so rethrow original
     }
     return joinedArray;
 }

이 방법의 관건 적 인 두 부분 은 코드 에 표 시 된 a, b 두 곳 이다.a 처 는 먼저 반사 적 인 방식 으로 array 1, array 2 길이 의 합 을 가 진 배열 joinedArray 를 정의 한 다음 에 array 1 을 joinedArray 에 복사 하고 b 처 는 array 2 를 joinedArray 에 복사 합 니 다.이 두 가 지 를 제외 하고 이상 처 리 는 주의해 야 한다. 이상 을 포착 한 후에 type 1 이 type 2 에 계승 되 었 는 지 아 닌 지 를 판단 했다. 즉, array 1 에 대응 하 는 유형 이 array 2 에 대응 하 는 유형 과 같 거나 array 1 에 대응 하 는 유형 이 array 2 에 대응 하 는 하위 클래스 인지 아 닌 지 를 판단 하 는 것 이다. 그렇지 않 으 면 호 환 되 지 않 는 상황 이 발생 할 것 이다.
(2) 예시
//       
String[] ff = ArrayUtils.addAll(aa, bb);

//                 
String[] gg = ArrayUtils.addAll(aa, "12", "13");
String[] hh = ArrayUtils.addAll(aa, "12", "13", "14");
String[] ii = ArrayUtils.addAll(aa, "12", "13", "14", "15");

//       
String[] jj =  ArrayUtils.addAll(aa, bb);
String[] kk =  ArrayUtils.addAll(jj, cc);

설명 이 필요 한 것 은 addAll () 의 두 번 째 매개 변 수 는 가 변 매개 변수 로 같은 유형의 값 이나 이 유형의 배열 을 여러 개 전달 할 수 있 습 니 다.
(3) 오류 처 리 는 제 가 사용 하 는 과정 에서 문제 가 발생 했 습 니 다. 구체 적 으로 다음 과 같 습 니 다. 코드 1:
String[] ll =  ArrayUtils.addAll(aa, bb, cc);

알림 에 따 르 면 addAll () 반환 값 유형 은 Serializable [] 이 며, 모든 것 은 String [] 호 환 을 마 실 수 없습니다.그래서 나 는 코드 를 다음 과 같은 코드 로 바 꾸 었 다. 코드 2:
ArrayUtils.addAll(aa, bb, cc);

나 는 반환 값 을 받 지 않 고 합병 만 하면 잘못 보고 하지 않 을 것 이 라 고 생각 했다. 비록 컴 파일 을 통 과 했 지만 운행 은 잘못 보고 되 었 다.오류 정 보 는 다음 과 같 습 니 다.
Exception in thread "main" java.lang.IllegalArgumentException: Cannot store java.io.Serializable in an array of java.lang.String
    at org.apache.commons.lang3.ArrayUtils.addAll(ArrayUtils.java:5084)
    at com.liu.date20170524.MergeArrays.main(MergeArrays.java:44)
Caused by: java.lang.ArrayStoreException
    at java.lang.System.arraycopy(Native Method)
    at org.apache.commons.lang3.ArrayUtils.addAll(ArrayUtils.java:5073)
    ... 1 more

당시 관성 사고 에 빠 져 addAll 과 List 등의 addAll () 방법 유형 이 여러 목록 (여 기 는 배열) 을 합 칠 수 있다 고 생각 했 기 때문에 오류 가 어디 에 있 는 지 알 수가 없 었 다.나중에 야 addAll () 의 두 번 째 매개 변수의 유형 은 T 이지 T [] 가 아니 기 때문에 두 개 이상 의 배열 을 합 칠 수 없다 는 것 을 알 게 되 었 다.여러분 께 서 교훈 으로 삼 으 시기 바 랍 니 다.
[참고]http://blog.csdn.net/jaycee110905/article/details/9179227

좋은 웹페이지 즐겨찾기