How to Check if an Array Contains a Value in Java Efficiently?

How to check if an array (unsorted) contains a certain value? This is a very useful and frequently used operation in Java. It is also a top voted question on Stack Overflow. As shown in top voted answers, this can be done in several different ways, but the time complexity could be very different. In the following I will show the time cost of each method.

 

1. Four Different Ways to Check If an Array Contains a Value

1) Using List:

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

2) Using Set:

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

3) Using a simple loop:

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

4) Using Arrays.binarySearch():
binarySearch() can ONLY be used on sorted arrays. If the array is sorted, you can use the following code to search the target element:

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

2. Time Complexity

The approximate time cost can be measured by using the following code. The basic idea is to search an array of size 5, 1k, 10k. The approach may not be precise, but the idea is clear and simple.

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

Result:

useList:  13
useSet:  72
useLoop:  5

Use a larger array (1k):

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

Result:

useList:  112
useSet:  2055
useLoop:  99
useArrayBinary:  12

Use a larger array (10k):

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

Result:

useList:  1590
useSet:  23819
useLoop:  1526
useArrayBinary:  12

Clearly, using a simple loop method is more efficient than using any collection. A lot of developers use the first method, but it is inefficient. Pushing the array to another collection requires spin through all elements to read them in before doing anything with the collection type.

The array must be sorted, if Arrays.binarySearch() method is used. In this case, the array is not sorted, therefore, it should not be used.

Actually, if you need to check if a value is contained in some array/collection efficiently, a sorted list or tree can do it in O(log(n)) or hashset can do it in O(1).

Category >> Array >> Java   If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:

<pre><code> 
String foo = "bar";
</code></pre>
  • Brandy Knapp Smallwood

    try this for(x=0;10>x;x++) { any code here}
    it will repeat

  • wenchao

    hashset can do it in O(1)? Why in your case, hastset is the slowest?

  • I dont know

    Is there a way to say “ignore case” while using

    Arrays.asList(arr).contains(targetValue)

  • Anttix

    Profiling with simple loops does not yield meaningful results.

    JVMs are smart and can optimize out code that produces data which is not consumed.
    Also the is the state of JIT caches, the garbage collector runs and other considerations.
    The bottom line is that in order to get meaningful results for small snippets you need to use a more elaborate benchmarking harness. e.g. JMH. See this excellent talk about benchmarking below

    http://shipilev.net/talks/devoxx-Nov2013-benchmarking.pdf

转载于:https://www.cnblogs.com/qinblog/p/10181639.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值