您的位置:首页 > 其它

怎样判断Array(无序)中是否包含某个值呢?

2016-11-05 12:21 239 查看

问题

怎样去判断Array(无序)中是否包含某个值呢?

这是一个在Java中经常被问到的问题。它也是Stack Overflow上投票前几的一个问题。下面将展示投票前几的几个回答,这些回答使用不同的方式解决了这个问题,但是,时间复杂度也是各有不同的。

四种解决方法

使用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);
}


使用Loop

public static boolean useLoop(String[] arr, String targetValue) {
for (String s : arr) {
if (s.equals(targetValue))
return true;
}
return false;
}


使用ArraysBinarySearch,这个方法只适用于已排序的Array

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的Array中进行查找。这个方法可能不够精确,但是这个思路还是很简单清晰的。

注:测试环境为win7-64+JDK1.6

使用Array大小为5

public static void main(String[] args) {
System.out.println("---------array size is 5-----------");
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+" 毫秒");
}


结果:

---------array size is 5-----------
useList: 10 毫秒
useSet: 66 毫秒
useLoop: 4 毫秒
useArrayBinary: 4 毫秒


### 使用Array大小为1k

System.out.println("---------array size is 1k----------");
String[] arr = new String[1000];
Random s = new Random();
for (int i = 0; i < 1000; i++) {
arr[i] = String.valueOf(s.nextInt());
}


结果:

---------array size is 1k----------
useList: 762 毫秒
useSet: 7549 毫秒
useLoop: 677 毫秒
useArrayBinary: 14 毫秒


使用Array大小为10k

System.out.println("---------array size is 10k---------");
String[] arr = new String[10000];
Random s = new Random();
for (int i = 0; i < 10000; i++) {
arr[i] = String.valueOf(s.nextInt());
}


结果:

---------array size is 10k---------
useList: 7395 毫秒
useSet: 126341 毫秒
useLoop: 5776 毫秒
useArrayBinary: 17 毫秒


总结

从测试的结果可以清楚地知道,使用简单的Loop比使用集合操作更加有效 。许多开发者使用List方式,但是那并不高效。把Array放到另一个Collection中需要读取Array中的所有元素,这将花费不少的时间。

使用Arrays.binarySearch()的前提是这Array必须是有序的。

实际上,如果你真正需要高效地去判断Array/Collection中是否包含某个值,一个排序了的List或者Tree的时间复杂度为O(log(n)),或者用HashSet,它的时间复杂度为O(1)。

原文链接:http://www.programcreek.com/2014/04/check-if-array-contains-a-value-java/

翻译:crane-yuan

[ 转载请保留原文出处、译者和译文链接。]​
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: