Java의 효율적인 판단 수조에 있는 요소의 존재 여부

5460 단어 java수조원소
1. 수조에 어떤 값이 포함되어 있는지 확인하는 방법
List 사용

public static boolean useList(String[] arr, String targetValue) {
  return Arrays.asList(arr).contains(targetValue);
}
Set 사용

public static boolean useSet(String[] arr, String targetValue) {
  Set<String> set = new HashSet<String>(Arrays.asList(arr));
  return set.contains(targetValue);
}
순환 판단을 사용하다

public static boolean useLoop(String[] arr, String targetValue) {
  for(String s: arr){
    if(s.equals(targetValue))
      return true;
  }
  return false;
}
Arrays를 사용합니다.binarySearch()Arrays.binarySearch() 방법은 질서수 그룹에만 사용됩니다!!!수조가 무질서하면 결과가 이상해.
다음 방법으로 일련 번호 그룹에 값을 포함할지 여부를 찾습니다.

public static boolean useArraysBinarySearch(String[] arr, String targetValue) { 
  int a = Arrays.binarySearch(arr, targetValue);
  if(a > 0)
    return true;
  else
    return false;
}
시간 복잡도
아래의 코드는 각종 방법의 시간 원가를 대충 얻어낼 수 있다.기본 사상은 수조에서 어떤 값을 찾는 것이다. 수조의 크기는 각각 5, 1k, 10k이다.이런 방법이 얻은 결과는 정확하지 않을 수도 있지만, 가장 간단하고 명확한 방식이다.

public static void main(String[] args) {
  String[] arr = new String[] { "CD", "BC", "EF", "DE", "AB"};

  //use list
  long startTime = System.nanoTime();
  for (int i = 0; i < 100000; i++) {
    useList(arr, "A");
  }
  long endTime = System.nanoTime();
  long duration = endTime - startTime;
  System.out.println("useList: " + duration / 1000000);

  //use set
  startTime = System.nanoTime();
  for (int i = 0; i < 100000; i++) {
    useSet(arr, "A");
  }
  endTime = System.nanoTime();
  duration = endTime - startTime;
  System.out.println("useSet: " + duration / 1000000);

  //use loop
  startTime = System.nanoTime();
  for (int i = 0; i < 100000; i++) {
    useLoop(arr, "A");
  }
  endTime = System.nanoTime();
  duration = endTime - startTime;
  System.out.println("useLoop: " + duration / 1000000);

  //use Arrays.binarySearch()
  startTime = System.nanoTime();
  for (int i = 0; i < 100000; i++) {
    useArraysBinarySearch(arr, "A");
  }
  endTime = System.nanoTime();
  duration = endTime - startTime;
  System.out.println("useArrayBinary: " + duration / 1000000);
}
실행 결과:

useList: 13
useSet: 72
useLoop: 5
useArraysBinarySearch: 9
1k 길이의 배열 사용하기

String[] arr = new String[1000];

Random s = new Random();
for(int i=0; i< 1000; i++){
  arr[i] = String.valueOf(s.nextInt());
}
결과:

useList: 112
useSet: 2055
useLoop: 99
useArrayBinary: 12
10k 길이의 배열 사용하기

String[] arr = new String[10000];

Random s = new Random();
for(int i=0; i< 10000; i++){
  arr[i] = String.valueOf(s.nextInt());
}
결과:

useList: 1590
useSet: 23819
useLoop: 1526
useArrayBinary: 12
작은 매듭
분명히 어떤 집합을 사용하는 것보다 간단한 순환 방법을 사용하는 것이 더 효율적이다.많은 개발자들이 편의를 위해 첫 번째 방법을 사용하지만 그의 효율도 상대적으로 낮다.컬렉션 형식에 그룹을 눌러야 하기 때문에, 우선 그룹 요소를 한 번 훑어본 다음 집합 클래스를 사용하여 다른 작업을 해야 합니다.Arrays.binarySearch() 방법을 사용하면 배열이 정렬되어야 합니다.위의 수조가 정렬되지 않았기 때문에 이 방법은 사용할 수 없습니다.
실제로 수조나 집합류를 빌려 수조에 특정한 값이 포함되어 있는지 효율적으로 검사해야 한다면, 정렬된 목록이나 트리는 시간 복잡도가 O(log(n)이고,hashset는 O(1)에 도달할 수 있다.
ArrayUtils 사용
상기 몇 가지 외에 아파치 커먼스 라이브러리에는 Array Utils 클래스가 제공되어 있으며, 그 contains 방법으로 수조와 값의 관계를 판단할 수 있다.

import org.apache.commons.lang3.ArrayUtils;
public static boolean useArrayUtils(String[] arr, String targetValue) {
  return ArrayUtils.contains(arr,targetValue);
}
마찬가지로 상기 몇 가지 길이의 수조를 사용하여 테스트를 실시한 결과 이 방법의 효율은 사용 집합과 사용 순환 판단 사이에 있다(때로는 결과가 심지어 사용 순환보다 이상적일 때도 있다).

useList: 323
useSet: 3028
useLoop: 141
useArrayBinary: 12
useArrayUtils: 181
-------
useList: 3703
useSet: 35183
useLoop: 3218
useArrayBinary: 14
useArrayUtils: 3125
사실, Array Utils를 보면contains의 원본 코드는 그가 원소가 수조에 포함되었는지 아닌지를 판단하는 것도 사실 순환 판단 방식을 사용하는 것을 발견할 수 있다.
부분 코드는 다음과 같습니다.

  if(array == null) {
    return -1;
  } else {
    if(startIndex < 0) {
      startIndex = 0;
    }

    int i;
    if(objectToFind == null) {
      for(i = startIndex; i < array.length; ++i) {
        if(array[i] == null) {
          return i;
        }
      }
    } else if(array.getClass().getComponentType().isInstance(objectToFind)) {
      for(i = startIndex; i < array.length; ++i) {
        if(objectToFind.equals(array[i])) {
          return i;
        }
      }
    }

    return -1;
  }
그래서 비교해 보면 저는 Array Utils 도구 종류를 사용하여 합수조와 관련된 조작을 하는 경향이 있습니다.어쨌든 그는 나로 하여금 많은 코드를 적게 쓰게 할 수 있다. (자신이 코드를 쓰는 데는 버그가 있기 마련이고, 아파치가 제공하는 소스 오픈 도구 라이브러리는 무수한 개발자들의 시련을 거친 것이기 때문이다.) 그리고 효율도 그리 낮지 않다.
총결산
자, 이상은 이 글의 전체 내용입니다. 본고의 내용이 여러분들이 자바를 배우거나 사용하는 데 어느 정도 도움이 되었으면 좋겠습니다. 의문이 있으면 댓글을 남겨 주십시오.

좋은 웹페이지 즐겨찾기