如何检查数组(未排序)是否包含某个值?这是Java中非常有用且经常使用的操作。这也是Stack Overflow上票数最高的问题。如票数最高的答案所示,这可以通过几种不同的方式完成,但是时间复杂度可能会大不相同。在下面,我将显示每种方法的时间成本。
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 set = new HashSet(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():
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);}
结果:
useList:13
useSet:72
useLoop:5
使用更大的数组(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()method ,则必须对数组进行排序。在这种情况下,数组未排序,因此不应使用它。
实际上,如果您需要检查某个数组/集合中是否有效包含某个值,则排序列表或树可以在其中进行处理O(log(n)),而哈希集可以在中进行处理O(1)。