版权声明:开源交流,可以不进行特殊介绍,但请尊重个人劳动成果,互相交流哦! https://blog.csdn.net/wanglizheng825034277/article/details/80481816
参照链接:http://www.hollischuang.com/archives/1269
查找效率对比表:
数组容量 | 查找次数 | List | Set | Loop | BinarySearch | ArrayUtils |
6 | 10 | 331390 | 38718 | 14571 | 34738(有序) | 13755 |
6 | 100000 | 42319492 | 204266488 | 7266007 | 11627486(有序) | 3777349 |
10 | 10 | 397205 | 926739 | 22571 | 无 | 17764 |
10000 | 10 | 7949871 | 42562837 | 3443155 | 无 | 53373 |
10000 | 10 | 4645222 | 50564550 | 4626643 | 99976(有序) | 55648 |
结果分析:
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.
}
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;
}
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;
}
ArrayUtils:ArrayUtils.contains(arr, targetValue),同样使用循环实现查找
public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
if (startIndex < 0) {
startIndex = 0;
}
if (objectToFind == null) {
for (int i = startIndex; i < array.length; i++) {
if (array[i] == null) {
return i;
}
}
} else {
for (int i = startIndex; i < array.length; i++) {
if (objectToFind.equals(array[i])) {
return i;
}
}
}
return INDEX_NOT_FOUND;
}
虽然大部分都是通过循环对比查找,但通过简单的代码测试,使用ArrayUtils.contains(arr, targetValue)是性能相对较高的选择。
查找代码:
public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
if (startIndex < 0) {
startIndex = 0;
}
if (objectToFind == null) {
for (int i = startIndex; i < array.length; i++) {
if (array[i] == null) {
return i;
}
}
} else {
for (int i = startIndex; i < array.length; i++) {
if (objectToFind.equals(array[i])) {
return i;
}
}
}
return INDEX_NOT_FOUND;
}
public static void main(String[] args) {
String[] arr = { "AB", "BC", "CD", "DE", "EF" };
int loopTime = 10;
// 当被查找的数组容量比较小时,查询耗时基本没有太大差别
// 查找10次
//useList : 331390
//useSet : 387718
//useLoop : 14571
//use ArrayBinary : 34738
//use ArrayUtils : 13755
// 查找100000次
//useList : 42319492
//useSet : 204266488
//useLoop : 7266007
//use ArrayBinary : 11627486
//use ArrayUtils : 3777349
// 查询10次,且大容量数组
//useList : 7949871
//useSet : 42562837
//useLoop : 3443155
//use ArrayBinary : 83144
//use ArrayUtils : 53373
// 查询10次,小容量数组
//useList : 397205
//useSet : 926739
//useLoop : 22571
//use ArrayBinary : 44114
//use ArrayUtils : 17764
// arr = new String[10];
// Random random = new Random();
// for (int i = 0; i < arr.length; i++) {
// arr[i] = String.valueOf(random.nextInt());
// }
long startTime = System.nanoTime();
for (int i = 0; i < loopTime; i++) {
useList(arr, "A");
}
long endTime = System.nanoTime();
System.out.println("useList : " + (endTime - startTime));
startTime = System.nanoTime();
for (int i = 0; i < loopTime; i++) {
useSet(arr, "A");
}
endTime = System.nanoTime();
System.out.println("useSet : " + (endTime - startTime));
startTime = System.nanoTime();
for (int i = 0; i < loopTime; i++) {
useLoop(arr, "A");
}
endTime = System.nanoTime();
System.out.println("useLoop : " + (endTime - startTime));
startTime = System.nanoTime();
for (int i = 0; i < loopTime; i++) {
useArraysBinarySearch(arr, "A");
}
endTime = System.nanoTime();
System.out.println("use ArrayBinary : " + (endTime - startTime));
startTime = System.nanoTime();
for (int i = 0; i < loopTime; i++) {
useArraysBinarySearch(arr, "A");
}
endTime = System.nanoTime();
System.out.println("use ArrayUtils : " + (endTime - startTime));
System.out.println((1 + 10) >>> 1);
}
public static boolean useArrayUtils(String[] arr, String targetValue) {
return ArrayUtils.contains(arr, targetValue);
}
// 使用binarySearch需要有序
public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
int a = Arrays.binarySearch(arr, targetValue);
if (a > 0) {
return true;
} else {
return false;
}
}
// 测试数组包含测试
public static boolean useList(String[] arr, String targetValue) {
return Arrays.asList(arr).contains(targetValue);
}
public static boolean useSet(String[] arr, String targetValue) {
Set<String> set = new HashSet<>(Arrays.asList(arr));
return set.contains(targetValue);
}
public static boolean useLoop(String[] arr, String targetValue) {
for (String str : arr) {
if (str.equals(targetValue)) {
return true;
}
}
return false;
}