七、如何在Java中高效检查一个数组是否含有一个值

如何检查一个数组(非排序的)是否包含特定的值。这是个非常有用或经常被在Java中使用。这是个在Stack Overflow中高得票的问题。在已经高得票的答案中,有许多不同的处理方法,但是时间的复杂度非常不同。在下面,我将会展示每种方法的时间花费。

 

 

一、四种不同的方法去检查一个数组包含特定的值

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)完成。

 

转载于:https://www.cnblogs.com/seaspring/p/5268369.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值