答:一般用簡(jiǎn)單的for循環(huán)就挺高效了。如下分析:
如何檢查一個(gè)未排序的數(shù)組中是否包含某個(gè)特定值,這是一個(gè)在java中非常實(shí)用并且頻繁使用的操作。另外,這也是Stack Overflow上面非常受關(guān)注的問(wèn)題。在得票數(shù)最多的答案中,可以看到,檢查數(shù)組中是否包含特定值可以用多種不同的方式實(shí)現(xiàn),但是時(shí)間復(fù)雜度差別很大。下面,我將為大家展示各種方法及其需要花費(fèi)的時(shí)間。
1.檢查數(shù)組中是否包含特定值的四種不同方法
1)使用List:
1 2 3 | public static boolean useList(String[] arr, String targetValue) { return Arrays.asList(arr).contains(targetValue); } |
2)使用Set:
1 2 3 4 | public static boolean useSet(String[] arr, String targetValue) { Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue); } |
3)使用一個(gè)簡(jiǎn)單循環(huán):
1 2 3 4 5 6 7 | public static boolean useLoop(String[] arr, String targetValue) { for(String s: arr){ if(s.equals(targetValue)) return true; } return false; } |
4)使用Arrays.binarySearch():
注:下面的代碼是錯(cuò)誤的,這樣寫出來(lái)僅僅為了理解方便。binarySearch()只能用于已排好序的數(shù)組中。所以,你會(huì)發(fā)現(xiàn)下面結(jié)果很奇怪。
1 2 3 4 5 6 7 | public static boolean useArraysBinarySearch(String[] arr, String targetValue) { int a = Arrays.binarySearch(arr, targetValue); if(a > 0) return true; else return false; } |
2.時(shí)間復(fù)雜度
通過(guò)下面的這段代碼可以近似比較幾個(gè)方法的時(shí)間復(fù)雜度。雖然分別搜索一個(gè)大小為5、1K、10K的數(shù)組是不夠精確的,但是思路是清晰的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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); } |
結(jié)果:
1 2 3 4 | useList: 13 useSet: 72 useLoop: 5 useArraysBinarySearch: 9 |
對(duì)于長(zhǎng)度為1K的數(shù)組:
1 2 3 4 5 6 | String[] arr = new String[1000];
Random s = new Random(); for(int i=0; i< 1000; i++){ arr[i] = String.valueOf(s.nextInt()); } |
結(jié)果:
1 2 3 4 | useList: 112 useSet: 2055 useLoop: 99 useArrayBinary: 12 |
對(duì)于長(zhǎng)度為10K的數(shù)組:
1 2 3 4 5 6 | String[] arr = new String[10000];
Random s = new Random(); for(int i=0; i< 10000; i++){ arr[i] = String.valueOf(s.nextInt()); } |
結(jié)果:
1 2 3 4 | useList: 1590 useSet: 23819 useLoop: 1526 useArrayBinary: 12 |
很明顯,使用簡(jiǎn)單循環(huán)的方法比使用其他任何集合效率更高。許多開發(fā)者會(huì)使用第一種方法,但是它并不是高效的。將數(shù)組壓入Collection類型中,需要首先將數(shù)組元素遍歷一遍,然后再使用集合類做其他操作。
如果使用Arrays.binarySearch()方法,數(shù)組必須是已排序的。由于上面的數(shù)組并沒有進(jìn)行排序,所以該方法不可使用。
實(shí)際上,如果你需要借助數(shù)組或者集合類高效地檢查數(shù)組中是否包含特定值,一個(gè)已排序的列表或樹可以做到時(shí)間復(fù)雜度為O(log(n)),hashset可以達(dá)到O(1)。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注