From http://www.hollischuang.com/archives/1269?
How do I check if an array (unordered) includes a specific value? This is a frequently used and very useful operation in Java. At the same time, this issue is also a very hot issue in stack overflow.
There are several different ways to get a few answers that are relatively high, but their time complexity varies. This article will analyze several common usage methods and their time cost.
Methods to check whether an array includes a value
Using the list
public static boolean useList(String[] arr, String targetValue) { return Arrays.asList(arr).contains(targetValue);}
Using Set
public static boolean useSet(String[] arr, String targetValue) { Set<String> set = new HashSet<String>(Arrays.asList(arr)); return set.contains(targetValue);}
Using loop Inference
public static boolean useLoop(String[] arr, String targetValue) { for(String s: arr){ if(s.equals(targetValue)) return true; } return false;}
Using Arrays.binarysearch ()
The Arrays.binarysearch () method can only be used for ordered arrays!
!!
Assuming that the array is unordered, the result will be very strange.
The use of finding out whether a value is included in an ordered array such as the following:
public static boolean useArraysBinarySearch(String[] arr, String targetValue) { int a = Arrays.binarySearch(arr, targetValue); if(a > 0) return true; else return false;}
Complexity of Time
The following code can approximate the time cost of various methods.
The basic idea is to find a value from the array, the size of the array is 5, 1k, 10k.
The result of such a method may not be accurate. But it's the simplest and clearest way.
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);}
Execution Result:
useList: 13useSet: 72useLoop: 5useArraysBinarySearch: 9使用一个长度为1k的数组String[] arr = new String[1000];Random s = new Random();for(int i=0; i< 1000; i++){ arr[i] = String.valueOf(s.nextInt());}
Results:
useList: 112useSet: 2055useLoop: 99useArrayBinary: 12
Use an array of length 10k
String[] arr = new String[10000];Random s = new Random();for(int i=0; i< 10000; i++){ arr[i] = String.valueOf(s.nextInt());}
Results:
useList: 1590useSet: 23819useLoop: 1526useArrayBinary: 12
Summarize
Obviously. Using a simple loop method is more efficient than using whatever set. Many developers use the first method for convenience, but his efficiency is relatively low. Because the array is pressed into the collection type, the array element is first traversed once, and then the collection class is used for other operations.
Assume that you use the Arrays.binarysearch () method. The array must be sorted.
Because the array above is not sorted, the method is not available.
In fact, suppose you need to use an array or a collection class to efficiently check whether a particular value is included in an array, a sorted list or tree can have a time complexity of O (log (n)), and HashSet can reach O (1).
(The English text ends, the following is the translator note)
Using Arrayutils
In addition to the above several. The Apache Commons Class library also provides a arrayutils class that can infer the relationship of arrays and values using its contains method.
import org.apache.commons.lang3.ArrayUtils;public static boolean useArrayUtils(String[] arr, String targetValue) { return ArrayUtils.contains(arr,targetValue);}
The same use of arrays of several lengths to test, the result is that the efficiency of the method between the use of the set and the use of cyclic inference (sometimes the result is even better than the use of loops).
useList: 323useSet: 3028useLoop: 141useArrayBinary: 12
usearrayutils:181
useList: 3703useSet: 35183useLoop: 3218useArrayBinary: 14useArrayUtils: 3125
In fact, assuming that the source code of the view Arrayutils.contains can be found, he infers whether an element is included in the array and in fact is a way of using loop inference.
Some of the code is as follows:
if(array == null) { return -1; } else { if(startIndex < 0) { startIndex = 0; } int i; if(objectToFind == null) { for(i = startIndex; i < array.length; ++i) { if(array[i] == null) { return i; } } } else if(array.getClass().getComponentType().isInstance(objectToFind)) { for(i = startIndex; i < array.length; ++i) { if(objectToFind.equals(array[i])) { return i; } } } return -1; }
So, in comparison, I prefer to use the Arrayutils tool class to do some composite ancestor related operations. After all, he can let me write a lot less code (because I write code inevitably have bugs, after all, Apache provides the open Source Tool class library has been tested by countless developers), and, the efficiency is not too low too much.
How to efficiently infer whether an element is included in an array in Java