2021-11-15

如何高效检查一个数组是否含有一个值

四种不同的方法去检查一个数组包含特定的值
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()
下面的代码是错误的,列出来是为了完备性。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

很明显,用简单的循环方法比用任何集合更有效。很多开发者用第一种方法,但是它是不高效的。传递数组给另外一个集合,在操作前,需要转换所有元素。 如果一个数组是排序的。如果Arrays.binarySearch()方法被使用。 在这种情况下,由于数组是没有排序的,所以它不能使用。 实际上,如果你真的需要去高效查找一个值是否在一个数组或集合中,一个排序的list或tree 可以在O(log(n))或hashset 可以在O(1)完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值