자바 의 Arrays 라 는 도구 류 를 정말 사용 할 수 있 습 니까?
오늘 자바 의 소스 코드 세 번 째 탄,Arrays 라 는 도구 류 의 소스 코드 를 공유 합 니 다.최근 에 데이터 구 조 를 복습 하면 서 Arrays 안의 정렬 알고리즘 과 이분 검색 등의 실현 을 알 게 되 었 고 수익 이 매우 많 기 때문에 Arrays 와 같은 소스 코드 를 연구 하기 로 결정 했다.부족 한 점 은 논평 구역 에서 교류 하고 지적 하 는 것 을 환영 합 니 다.
1.Arrays 클래스 를 알 고 있 습 니 다.
우선 자바 의 utils 패키지 아래 자바 Collections Framework 의 일원 입 니 다.그것 의 취 지 는 바로 도구 류 로 배열 을 조작 하 는 여러 가지 방법 을 밀봉 했다.예 를 들 어 정렬,2 분 검색,배열 의 복사 등 이다.우리 가 일상적으로 수조 체조 에 대한 기본 적 인 수 요 를 만족 시 키 고 그 밑바닥 의 실현 을 이해 하면 우리 가 그것 을 더욱 잘 사용 할 수 있 을 뿐만 아니 라 더 좋 은 코드 의 사고방식 도 키 울 수 있다.
2.구조 방법
도구 류 이기 때문에 그 구조 방법 은 사유 로 정의 되 고 모든 실현 방법 은 정적 방법 이다.즉,이런 종 류 는 실례 화 되 어 서 는 안 되 고,통속 적 으로 말 하면 new 가 안 된다 는 것 이다.클래스 이름 을 통 해서 만 직접 호출 방법(반사 제외).이렇게 하 는 목적 은 이런 실 용화 할 수 없 는 능력 을 강화 하고 이런 도구 류 로 서 의 근본 적 인 기능 을 강조 하 는 것 이다.원본 코드 는 다음 과 같 습 니 다.
 // Suppresses default constructor, ensuring non-instantiability.
 private Arrays() 
{
}3.상용 방법의 해석3.1 집합 요 소 를 빠르게 삽입 하 는 방법 asList(T...a):
기본 사용:
 /**
  *        
  */
 @Test
 public void toArrayTest(){
  List<Integer> list = Arrays.asList(2,4,5,6,6);
  for (Integer integer : list) {
   System.out.print(integer+" ");
  }
 }출력 결과:2 4 5 6 6
원본 코드 보기:
@SafeVarargs
 @SuppressWarnings("varargs")
 public static <T> List<T> asList(T... a) {
  return new ArrayList<>(a);
 }
// ArrayList        
  private final E[] a;
  ArrayList(E[] array) {
   a = Objects.requireNonNull(array);
  }이 방법의 실현 은 비교적 간단 하 다.바로 Array List 의 구조 방법 을 호출 하 는 것 이 고 매개 변 수 는 하나의 배열 이다.즉,우리 가 구성 하고 자 하 는 수 를 Array List 의 구조 방법 에 전달 하여 예화 하 는 것 이다.3.2 2 점 에서 찾 는 방법
Arrays 클래스 의 2 분 검색 8 가지 기본 유형 은 모두 관련 되 어 있 지만 모두 방법의 과부하 입 니 다.그 실현 원 리 는 모두 같다.여기 서 int 유형 을 예 로 들 어 설명 한다.
기본 사용:
 @Test
 public void binarySearchTest(){
  int[] arrays = {1,4,6,7,9,3};
  //      7    
  int result = Arrays.binarySearch(arrays,7);
  System.out.println(result);
 }결과:3
이 방법 은 주로 세 가지 방법 과 관련된다.
//        
public static int binarySearch(int[] a, int key) {
  return binarySearch0(a, 0, a.length, key);
 }
/*
       : a       
 fromIndex        
 toIndex         
 key         
 */
public static int binarySearch(int[] a, int fromIndex, int toIndex,
         int key) {
  //       
  rangeCheck(a.length, fromIndex, toIndex);
  return binarySearch0(a, fromIndex, toIndex, key);
 }
 // Like public version, but without range checks.
 private static int binarySearch0(int[] a, int fromIndex, int toIndex,
          int key) {
  int low = fromIndex;
  int high = toIndex - 1;
  while (low <= high) {
    
   //           
   int mid = (low + high) >>> 1;
   int midVal = a[mid];
   
   //     
   if (midVal < key)
    low = mid + 1;
   else if (midVal > key)
    high = mid - 1;
   else
    return mid; // key found
  }
  return -(low + 1); // key not found.
 }물론 실현 의 핵심 방법 은 상술 한 사유 방법binarySearch0()이라는 방법 이기 때문에 실현 의 논리 도 복잡 하지 않다.첫 번 째 단 계 는 두 변수 가 검색 영역 을 저장 하 는 시작 과 끝 을 설명 하 는 것 입 니 다.
두 번 째 순환,비교,비교 범 위 를 계속 축소 합 니 다.배열 의 값 과 목표 값 이 같 을 때 까지 다음 표 시 를 되 돌려 줍 니 다.찾 지 못 하면 마이너스,즉 아래 의 l 두 줄 코드 를 되 돌려 줍 니 다.
return mid; // key found
return -(low + 1); // key not found.나 는 이 이분법 이 실현 하 는 하 이 라 이 트 는 바로 중간 값 의 이동 연산 을 구 하 는 것 이 라 고 생각한다.
int mid = (low + high) >>> 1;어떤 사람 은 왜 이 위 연산 을 사용 해 야 하 는 지,나눗셈 이 안 되 는 지 궁금 해 했다.주로 성능 을 고려 하기 위해 서다.이 위 연산 은 두 기계 주 기 를 차지 하고 곱셈 법 은 네 개의 연산 주 기 를 차지 하기 때문에 이 위 연산 의 속 도 는 곱셈 법의 연산 속도 보다 훨씬 빠 를 것 이다.계 산 량 이 작 으 면 차이 가 크 지 않 을 수 있 지만 계 산 량 이 많 으 면 차이 가 매우 뚜렷 하 다.3.3 배열 의 복사
 @Test
 public void testCopyArrange(){
   //    
  int [] srcArray = {11,2,244,5,6,54};
  //         3   
  int[] descArray = Arrays.copyOf(srcArray,3);
  
  System.out.println(Arrays.toString(descArray));
 }출력 결과:[11, 2, 244]
소스 코드 분석:
/*     :
 original    
 newLength         
 */
public static int[] copyOf(int[] original, int newLength) {
   //           ,        
  int[] copy = new int[newLength];
  System.arraycopy(original, 0, copy, 0,
       Math.min(original.length, newLength));
  return copy;
 }
public static native void arraycopy(Object src, int srcPos,
          Object dest, int destPos,
          int length);분석:주로 로 컬 방법 인 array copy 를 호출 하여 배열 의 지정 한 길 이 를 복사 한 것 입 니 다.소스 코드 가 배열 의 길 이 를 검사 하지 않 은 것 을 볼 수 있 습 니 다.주로arraycopy()이 방법 을 사용 할 때Math.min()방법 을 사용 하여 성명 의 길 이 를 안전 한 범위 내 에서 보장 합 니 다.만약 에 복사 한 길이 가 배열 의 길 이 를 초과 하면...모든 배열 을 기본 으로 복사 합 니 다.네 이 티 브 수식 방법 에 대해 서 는 사용 할 수 있 습 니 다여기 봐 봐..
 System.arraycopy(original, 0, copy, 0,
       Math.min(original.length, newLength));물론 배열 이 지정 한 구간 을 복사 해 야 한다 면 ArrayscopyOfRange(int[] original, int from, int to)의 실현 원리 와arraycopy()방법의 원 리 를 유사 하 게 사용 할 수 있다.
@Test
 public void testCopy(){
  int [] srcArray = {11,2,244,5,6,54};
   //          
  int[] descArray = Arrays.copyOfRange(srcArray,0,3);
  System.out.println(Arrays.toString(descArray));
 }출력 결과:[11, 2, 244]
주:
copyOfRange(int[] original, int from, int to)의 매개 변 수 는 복사 결과 에 포함 되 지 않 습 니 다.상기 예 는 색인 이 2 인 요소 만 복사 할 수 있 고 색인 이 3 인 요 소 는 포함 되 지 않 습 니 다.이 점 은 주의해 야 합 니 다.3.4 equals 방법
주로 Object 류 의 equals 방법 을 재 작성 하여 두 배열 의 내용 이 같 는 지,즉 그들 중의 요소 가 같 는 지 비교 하 는 데 사용 합 니 다.
기본 용법:
 @Test
 public void equalTest(){
  int[] array ={1,2,3,4};
  int[] result ={1,2,3,4};
  System.out.println(Arrays.equals(array,result)); 
  System.out.println(array == result);
 }결과:true
false
소스 코드 를 보기 전에 equals 방법 을 다시 쓴 후에 두 대상 이 비교 하 는 것 은 값,즉 그들의 내용 이라는 점 이 매우 중요 하 다.equals 방법 을 다시 쓰 는 주의사항여기 로 옮 겨..
원본 코드 는 다음 과 같 습 니 다.
 public static boolean equals(int[] a, int[] a2) {
  //        
  if (a==a2)
   return true;
  if (a==null || a2==null)
   return false;
  int length = a.length;
  //        
  if (a2.length != length)
   return false;
  
  //           
  for (int i=0; i<length; i++)
   if (a[i] != a2[i])
    return false;
  return true;
 }소스 코드 설명 은 다음 과 같 습 니 다.소스 코드 는 네 번 의 판단 을 했 는데 각각 첫 번 째 주소 비교,비어 있 는 지,그리고 길이 의 비교 이 고 마지막 으로 배열 의 각 요 소 를 비교 했다.
다음 의 첫 번 째 판단,즉 첫 번 째 주소 의 비 교 를 설명 할 필요 가 있다.우리 가 배열 변 수 를 설명 할 때 이 변 수 는 배열 의 첫 번 째 주 소 를 대표 합 니 다.아래 코드 를 보 세 요.
 @Test
 public void equalTest(){
  int[] array ={1,2,3,4};
  System.out.println(array);
  
 }결과:[I@4f2410ac // [대표 배열 I 대표 정수@구분자 뒤에 있 는 메모리 주소 16 진수
이것 은 주 소 를 나타 낸다.아니면 하나의 배열 을 설명 할 때 더미 안에 메모리 영역 을 만 들 기 때 문 입 니까?그러나 이 메모리 영역 은 더미 에 비해 작 을 수 있 습 니 다.찾기 가 쉽 지 않 습 니 다.찾기 편 하도록 배열 메모리 의 첫 주 소 를 표시 합 니 다.가상 컴퓨터 는 변수 이름 array 에 주 소 를 전달 합 니 다.이것 도 참조 형식 입 니 다.주소,즉 array 가 메모리 주 소 를 가리 키 는 것 으로 이해 합 니 다.실행 할 때마다 주소 가 다 를 수 있 습 니 다.가상 컴퓨터 가 열 린 메모리 공간 이 다 를 수 있 기 때 문 입 니 다.
이것 을 이해 하면
a==a2이해 하기 쉽다.만약 두 그룹의 메모리 주소 가 모두 같다 면 두 그룹의 메모리 주 소 는 틀림없이 같다.그리고 프로그램 이 비교적 잘 쓴 곳 은 바로 소스 코드 에서 배열 의 모든 요소 에 대한 비교,즉 아래 의 이 코드 라 고 생각 합 니 다.
for (int i=0; i<length; i++)
   if (a[i] != a2[i])
    return false;
  return true;판단 조건 으로 사용a[i] != a2[i]하면 비교 횟수 를 줄 이 고 성능 을 높 일 수 있다.만약 에 여기 가 똑 같은 비교 라면 매번 전체 배열 을 옮 겨 다 녀 야 한다.만약 에 데이터 의 양 이 많 으 면 성능 이 많이 느 릴 것 이다.또 한 번 소스 의 매력 에 감탄 했다.3.5 정렬 방법 sort()와 parallelsert()
Arrays이 유형 은 주로 두 가지 유형의 정렬 방법 직렬sort()과 병렬parallelSort()두 가지 방법 과 관련 되 는데 물론 대상 의 정렬 과 기본 유형의 정렬 도 다르다.여 기 는 int[]유형의 예 입 니 다.설명 을 하 다.먼저 두 가지 방법의 성능 을 비교한다.
 public final int UPPER_LIMIT = 0xffffff;
 final int ROUNDS = 10;
 final int INCREMENT = 5;
 final int INIT_SIZE = 1000;
 @Test
 public void sortAndParallelSortTest(){
  
  //          
  for (int capacity = INIT_SIZE; capacity < UPPER_LIMIT ; capacity*= INCREMENT) {
   ArrayList<Integer> list = new ArrayList<>(capacity);
   for (int j = 0; j < capacity; j++) {
    list.add((int) (Math.random()*capacity));
   }
   
   double avgTimeOfParallelSort = 0;
   double avgTimeOfSort = 0;
   for (int j = 0; j <= ROUNDS ; j++) {
    //          
    Collections.shuffle(list);
    Integer[] arr1 = list.toArray(new Integer[capacity]);
    Integer[] arr2 = arr1.clone();
     
    avgTimeOfParallelSort += counter(arr1,true);
    avgTimeOfSort += counter(arr2, false);
   }
   //     
   output(capacity,avgTimeOfParallelSort/ROUNDS,avgTimeOfSort/ROUNDS);
  }
 }
 private void output(int capacity, double v, double v1) {
  System.out.println("=======================       =========");
  System.out.println("Capacity"+capacity);
  System.out.println("ParallelSort"+v);
  System.out.println("Sort"+v1);
  System.out.println("       :"+(v < v1 ? "ParallelSort":"Sort"));
 }
 //        
 private double counter(Integer[] arr1, boolean b) {
  long begin,end;
  begin = System.nanoTime();
  if(b){
   Arrays.parallelSort(arr1);
  }else{
   Arrays.parallelSort(arr1);
  }
  end = System.nanoTime();
  return BigDecimal.valueOf(end-begin,9).doubleValue();
 }부분의 테스트 결과:===========================테스트 정렬 의 시간================
Capacity1000
ParallelSort6.284099999999999E-4
Sort5.599599999999999E-4
비교적 빠 른 정렬 은:Sort
===========================테스트 정렬 의 시간================
Capacity5000
ParallelSort0.00163599
Sort0.0018313699999999995
빠 른 정렬 은:ParallelSort
데이터 양 이 비교적 적은 상황 에서 sort()방법 을 사용 하 는 것 이 빠 르 고 한 한도 값 이 지나 면 ParallelSort()라 는 방법 이 성능 이 좋 은 것 을 볼 수 있 습 니 다.이 한도 값 은 얼마 일 까요?
먼저 parallelsert 의 소스 코드 를 살 펴 보 겠 습 니 다.
public static void parallelSort(int[] a) {
  int n = a.length, p, g;
  if (n <= MIN_ARRAY_SORT_GRAN ||
   (p = ForkJoinPool.getCommonPoolParallelism()) == 1)
   DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0);
  else
   new ArraysParallelSortHelpers.FJInt.Sorter
    (null, a, new int[n], 0, n, 0,
     ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
     MIN_ARRAY_SORT_GRAN : g).invoke();
 }배열 의 길이 가MIN_ARRAY_SORT_GRAN보다 작 거나p = ForkJoinPool.getCommonPoolParallelism()) == 1(단일 스 레 드 에서)일 때 sort()정렬 의 바 텀 을 호출 하여 이 루어 진DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0);Arrays 의 시작 정 의 는 다음 과 같 습 니 다.
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13; //     8192두 가 지 를 비교 하면 배열 의 길이 가 비교적 크 거나 다 중 스 레 드 의 경우 병렬 정렬 을 우선 고려 하고 그렇지 않 으 면 직렬 정렬 을 사용 하 는 것 이다.두 정렬 의 핵심 사상:
3.6 toString 방법
기본 용법:
 @Test
 public void toStringTest(){
   int[] array = {1,3,2,5};
  System.out.println(Arrays.toString(array));
 }결과:[1, 3, 2, 5]
소스 코드 분석 은 다음 과 같다.
 public static String toString(int[] a) {
  // 1.       
  if (a == null)
   return "null";
  int iMax = a.length - 1;
  if (iMax == -1)
   return "[]";
  
  // 2.  StringBuilder    
  StringBuilder b = new StringBuilder();
  b.append('[');
  for (int i = 0; ; i++) {
   b.append(a[i]);
   if (i == iMax)
    return b.append(']').toString();
   b.append(", ");
  }
 }구체 적 인 실현 은 이미 소스 코드 의 주석 에서 설명 되 었 다.이 방법 은 기본 데이터 형식 에 있어 서 배열 을 편리 하 게 옮 겨 다 닌 다.근본 을 캐 고 근원 을 거 슬러 야만 활보 하여 앞으로 나 아 갈 수 있다.
참고 자료
https://www.jb51.net/article/180770.htm
https://www.jb51.net/article/116323.htm
javaSE 의 공식 문서.
자바 에 있 는 Arrays 라 는 도구 류 를 사용 할 수 있 습 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.