程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java中高效的判別數組中某個元素能否存在詳解

Java中高效的判別數組中某個元素能否存在詳解

編輯:關於JAVA

Java中高效的判別數組中某個元素能否存在詳解。本站提示廣大學習愛好者:(Java中高效的判別數組中某個元素能否存在詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是Java中高效的判別數組中某個元素能否存在詳解正文


一、反省數組能否包括某個值的辦法

運用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

小結

顯然,運用一個復雜的循環辦法比運用任何集合都愈加高效。許多開發人員為了方便,都運用第一種辦法,但是他的效率也絕對較低。由於將數組壓入Collection類型中,首先要將數組元素遍歷一遍,然後再運用集合類做其他操作。

假如運用Arrays.binarySearch()辦法,數組必需是已排序的。由於下面的數組並沒有停止排序,所以該辦法不可運用。

實踐上,假如你需求借助數組或許集合類高效地反省數組中能否包括特定值,一個已排序的列表或樹可以做到時間復雜度為O(log(n)),hashset可以到達O(1)。

運用ArrayUtils

除了以上幾種以外,Apache Commons類庫中還提供了一個ArrayUtils類,可以運用其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

其實,假如檢查ArrayUtils.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;
  }

所以,相比擬之下,我更傾向於運用ArrayUtils工具類來停止一些合數祖相關的操作。畢竟他可以讓我少寫很多代碼(由於自己寫代碼難免有Bug,畢竟apache提供的開源工具類庫都是經過有數開發者考驗過的),而且,效率上也並不低太多。

總結

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家學習或許運用Java能有一定的協助,假如有疑問大家可以留言交流。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved