您的位置:首页 > 其它

如何高效检查一个数组中是否包含某个值?

2016-08-31 21:37 274 查看
转载地址:http://www.diguage.com/archives/112.html

1、不同的实现方式

1) 使用
List


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


public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
}
3) 使用循环:

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


public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
if (a > 0) {
return true;
} else {
return false;
}
}

2、时间复杂度

使用如下代码来粗略比较不同实现间的时间复杂度。虽然不是很精确,但是思路确实正确的。我们将看看数组在有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:  12
useSet:  65
useLoop:  2
useArrayBinary:  7

使用大一点的数组(1k个元素):

int length = 1000;
String[] arr = new String[length];

Random s = new Random();
for (int i = 0; i < length; i++) {
arr[i] = String.valueOf(s.nextInt());
}
结果:
useList:  115
useSet:  2010
useLoop:  97
useArrayBinary:  9
使用更大一点的元素(10k个元素):

int length = 10000;
String[] arr = new String[length];

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

结果:

useList: 1678
useSet: 25609
useLoop: 1802
useArrayBinary: 10从上面的结果可以清晰看到,使用简单循环的相比使用其他集合操作更高效。很多很多开发人员使用第一种方法,但是它并不是最高效的。将数组转化成其他的任何集合类型都需要先将所有元素读取到集合类中,才能对这个集合类型做其他的事情。
当使用
Arrays.binarySearch()
方法时,数组必须是排好序的。如果数组不是排好序的,则不能使用这个方法。

事实上,如果你真的需要高效地检查一个数组或者集合中是否包含一个值,一个排好序的数组或者树可以达到
O(log(n))
的时间复杂度,
HashSet
甚至能达到
O(1)
的时间复杂度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: