在Java中如何高效的判断数组中是否包含某个元素
Arrays.asList
Arrays.asList的作用是将数组转化为list,一般是用于在初始化的时候,设置几个值进去,简化代码,省去add的部分。
List<String> ebsCodes = Arrays.asList("USERNAME","REAP","NLS");
也可以使数组[但是数组类型不能是(byte,short,int,long,float,double,boolean),可以是integer等。
String[] s = {"aa","bb","cc"};
List<String> strlist = Arrays.asList(s);
注意
(1)该方法不适用于基本数据类型(byte,short,int,long,float,double,boolean),可以是integer。
(2)该方法将数组与列表链接起来,当更新其中之一时,另一个自动更新
(3)不支持add和remove方法
1 List
public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}
源码
源码List:Arrays.asList(arr).contains(targetValue),使用循环查找
/**
* Returns the index of the first occurrence of the specified element
* in this list, or -1 if this list does not contain the element.
* More formally, returns the lowest index <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>,
* or -1 if there is no such index.
*/
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
2 Set
public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
}
Set使用的是HashSet的contains方法(HashSet底层HashMap实现),通过hash值循环对比查找
/**
* Implements Map.get and related methods
*
* @param hash hash for key
* @param key the key
* @return the node, or null if none
*/
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
3循环判断
public static boolean useLoop(String[] arr, String targetValue) {
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
}
4 Arrays.binarySearch()
Arrays.binarySearch()方法只能用于有序数组!!!如果数组无序的话得到的结果就会很奇怪。
public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
if(a > 0)
return true;
else
return false;
}
源码 BinarySearch(查找数组必须有序): 源码使用二分查找实现元素查找
private static int binarySearch0(Object[] a, int fromIndex, int toIndex,
Object key) {
int low = fromIndex;
int high = toIndex - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
@SuppressWarnings("rawtypes")
Comparable midVal = (Comparable)a[mid];
@SuppressWarnings("unchecked")
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
5 ArrayUtils
import org.apache.commons.lang3.ArrayUtils;
public static boolean useArrayUtils(String[] arr, String targetValue) {
return ArrayUtils.contains(arr,targetValue);
}
ArrayUtils.contains
的源码 ArrayUtils.contains(arr, targetValue),同样使用循环实现查找
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;
}
总结
使用一个简单的循环方法比使用任何集合都更加高效。许多开发人员为了方便,都使用第一种方法,但是他的效率也相对较低。因为将数组压入Collection类型中,首先要将数组元素遍历一遍,然后再使用集合类做其他操作