首页编程java编程java数组为什么查询快 为什么java中数组的效率比集合高

java数组为什么查询快 为什么java中数组的效率比集合高

编程之家2023-10-11104次浏览

各位老铁们好,相信很多人对java数组为什么查询快都不是特别的了解,因此呢,今天就来为大家分享下关于java数组为什么查询快以及为什么java中数组的效率比集合高的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

java数组为什么查询快 为什么java中数组的效率比集合高

java中ArrayList为什么比LinkedList查询速度快

因为ArrayList是以数组的方式储存的,得到数据直接用下标就可以了,删除也直接根据下标就删除了,用ArrayList查询时最快的;而LinkedList是以双向链表的形式储存的,删除和增加数据速度快,只要把两边的指向变化就可以了。而ArrayList删除和增加数据都涉及到数据的移动问题,相对而言慢点。

为什么java中数组的效率比集合高

list集合的遍历3种方法:

[java] view plaincopy

java数组为什么查询快 为什么java中数组的效率比集合高

package com.sort;

import java.util.ArrayList;

java数组为什么查询快 为什么java中数组的效率比集合高

import java.util.Iterator;

import java.util.List;

/**

* list的三种遍历

*@author Owner

*

*/

public class ListTest{

public static void main(String[] args){

List<String> list= new ArrayList<String>();

list.add("a");

list.add("b");

list.add("c");

list.add("c");//可添加重复数据

//遍历方法一

for(Iterator<String> iterator= list.iterator();iterator.hasNext();){

String value= iterator.next();

System.out.println(value);

}

//遍历方法二

for(String value: list){

System.out.println(value);

}

//遍历方法三

for(int i=0;i<list.size();i++){

System.out.println(list.get(i));

}

}

}

三种遍历的比较分析:

方法一遍历:

执行过程中会进行数据锁定,性能稍差,同时,如果你想在循环过程中去掉某个元素,只能调用it.remove方法。

方法二遍历:

内部调用第一种

方法三遍历:

内部不锁定,效率最高,但是当写多线程时要考虑并发操作的问题

List接口的两种主要实现类ArrayList和LinkedList都可以采用这样的方法遍历

关于ArrayList与LinkedList的比较分析

a) ArrayList底层采用数组实现,LinkedList底层采用双向链表实现。

b)当执行插入或者删除操作时,采用LinkedList比较好。

c)当执行搜索操作时,采用ArrayList比较好。

java根据一个数字 怎么能快速的查询到 他在哪个A B 之间

首先要确定你的地域信息是怎么判定的,需要IP的哪些位?

IP分为4段,每段3位。从头到尾,不足不零。

可以形成。最大不超过12位的IP整数。要追求速度,首先需要将12位完整的IP中的某一部分脱离开。现在只需要除开IP段中的某一个段。即能取到9位的整数。这时,java中int类型支持的数字大小是20亿,即10位数,那仅取三段的IP满足int【Integer】的条件。当然,如果像LZ说的,取startIP和endIP,是否就是只二段?这样也可。我说的三段,是需要舍去一段。

现在将刚才我们得到的int型做为Map的key。

为什么要用Integer?下面分析。

首先查询最快的,肯定是HashMap。这里不得不说下HashMap的原理。

1、HashMap里添加一个元素。hashMap.put(key,value);是取Key值的hashCode,经过HashMap的hash(int)的运算,直接得到在HashMap中键数组中应该位于的下标。再将Key和Value的Entry【含Key,Value】放到HashMap里。注意。。是没有明显的遍历操作的。

2、从HashMap中取值,是怎么做的呢?同样,hashMap.get(key)是直接由key值的hashCode得key在键数组中的下标,再取出对应Entry【含Key,Value】。。同样。。没有明显的遍历操作的。

上面2步可以统称为:HashMap的hash算法。具体的实现。你可以去看jdk的源码。

现在就可以回到最开始的,为什么要用Integer类型做key,因为。。Integer重写了hashCode方法。他是直接返回Integer的value字段的,而Integer的eqauls方法甚至直接用的==操作符,这两点决定了高效性,。而String的eqauls和hashCode也重写了,但运算量远大于Integer的。对于HashMap来说,hashCode()和equals()方法,是取值,添加值都会用的。以下会把相关JDK代码贴出来。------如果实在不能用Integer,建议用Long。long的equals用的也是==,hashCode只是对value值进行了无符号右移32位再与原value值取“异或运算”。return(int)(value ^(value>>> 32));

为什么不用TreeMap呢。我分析了TreeMap的实现。他是这样做的。

1、TreeMap里添加元素。put(key,value),是首先,TreeMap,需要一个对Key的比较器,因为TreeMap是有序的,他的添加是由Key,先找到Key在键数组的位置,再将key,value的Entry放到对应位置。同时设置Entry的前一个和后一个Entry。形成有序Map。在查找Key的位置时,用的是树查找【二叉查找】,从根节点,依次查找。

2、TreeMap里取元素:同样的。用二叉查询方法,找到Key对应的Entry。从而得到Key,Value值。

我做了实验。分别在

1、HashMap里添加1000000条Integer键,String值的随机元素。用时,2500左右毫秒,然后再循环查询10000条随机数据,用时70毫秒左右。

2、TreeMap里做相同的操作,耗时分别为:2800毫秒和95毫秒。

可以认证上述观点。

综上所述。你应该用HashMap做为容器,用Integer做为键。能达到最快查询速度。

下面贴出相关代码。是在JDK1.6的源码里贴出来的。有兴趣的话,可以看一下。

HashMap:

public V put(K key, V value){

if(key== null)

return putForNullKey(value);

int hash= hash(key.hashCode());

int i= indexFor(hash, table.length);

for(Entry<K,V> e= table[i]; e!= null; e= e.next){

Object k;

if(e.hash== hash&&((k= e.key)== key|| key.equals(k))){

V oldValue= e.value;

e.value= value;

e.recordAccess(this);

return oldValue;

}

}

modCount++;

addEntry(hash, key, value, i);

return null;

}

static int indexFor(int h, int length){

return h&(length-1);

}

public V get(Object key){

if(key== null)

return getForNullKey();

int hash= hash(key.hashCode());

for(Entry<K,V> e= table[indexFor(hash, table.length)];

e!= null;

e= e.next){

Object k;

if(e.hash== hash&&((k= e.key)== key|| key.equals(k)))

return e.value;

}

return null;

}

TreeMap:

public V put(K key, V value){

Entry<K,V> t= root;

if(t== null){

// TBD:

// 5045147:(coll) Adding null to an empty TreeSet should

// throw NullPointerException

//

// compare(key, key);// type check

root= new Entry<K,V>(key, value, null);

size= 1;

modCount++;

return null;

}

int cmp;

Entry<K,V> parent;

// split comparator and comparable paths

Comparator<? super K> cpr= comparator;

if(cpr!= null){

do{

parent= t;

cmp= cpr.compare(key, t.key);

if(cmp< 0)

t= t.left;

else if(cmp> 0)

t= t.right;

else

return t.setValue(value);

} while(t!= null);

}

else{

if(key== null)

throw new NullPointerException();

Comparable<? super K> k=(Comparable<? super K>) key;

do{

parent= t;

cmp= k.compareTo(t.key);

if(cmp< 0)

t= t.left;

else if(cmp> 0)

t= t.right;

else

return t.setValue(value);

} while(t!= null);

}

Entry<K,V> e= new Entry<K,V>(key, value, parent);

if(cmp< 0)

parent.left= e;

else

parent.right= e;

fixAfterInsertion(e);

size++;

modCount++;

return null;

}

public V get(Object key){

Entry<K,V> p= getEntry(key);

return(p==null? null: p.value);

}

final Entry<K,V> getEntry(Object key){

// Offload comparator-based version for sake of performance

if(comparator!= null)

return getEntryUsingComparator(key);

if(key== null)

throw new NullPointerException();

Comparable<? super K> k=(Comparable<? super K>) key;

Entry<K,V> p= root;

while(p!= null){

int cmp= k.compareTo(p.key);

if(cmp< 0)

p= p.left;

else if(cmp> 0)

p= p.right;

else

return p;

}

return null;

}

Integer的hashCode和 equals方法:

public int hashCode(){

return value;

}

public boolean equals(Object obj){

if(obj instanceof Integer){

return value==((Integer)obj).intValue();

}

return false;

}

String:的hashCode和 equals方法:

public int hashCode(){

int h= hash;

int len= count;

if(h== 0&& len> 0){

int off= offset;

char val[]= value;

for(int i= 0; i< len; i++){

h= 31*h+ val[off++];

}

hash= h;

}

return h;

}

public boolean equals(Object anObject){

if(this== anObject){

return true;

}

if(anObject instanceof String){

String anotherString=(String)anObject;

int n= count;

if(n== anotherString.count){

char v1[]= value;

char v2[]= anotherString.value;

int i= offset;

int j= anotherString.offset;

while(n--!= 0){

if(v1[i++]!= v2[j++])

return false;

}

return true;

}

}

return false;

}

在Java中,如何检测一个数组中是否包含某一个数据

在Java中,检测一个数组是否包含某一个数据,通常有四种方法:

(1)for循环

(2)转换为List,调用Arrays.asList(arr).contains方法

(3)使用Set

(4)使用Arrays.binarySearch()方法

下面为上述四种方法的具体代码实现:

1、使用for循环

publicstaticbooleanuseLoop(String[]arr,StringtargetValue){

for(Strings:arr){

if(s.equals(targetValue))

returntrue;

}

returnfalse;

}

2、转换为List,调用Arrays.asList(arr).contains方法

publicstaticbooleanuseList(String[]arr,StringtargetValue){

returnArrays.asList(arr).contains(targetValue);

}

3、使用Set

publicstaticbooleanuseSet(String[]arr,StringtargetValue){

Set<String>set=newHashSet<String>(Arrays.asList(arr));

returnset.contains(targetValue);

}

4、使用Arrays.binarySearch()方法

特别说明:binarySearch()二分查找仅适用于有序数组,如果不是有序数组,则报异常

publicstaticbooleanuseArraysBinarySearch(String[]arr,StringtargetValue){

inta=Arrays.binarySearch(arr,targetValue);

if(a>0){

returntrue;

}else{

returnfalse;

}}

扩展资料:

Java种List列表的contains方法:

该方法是通过遍历集合中的每一个元素并用equals方法比较是否存在指定的元素。

publicbooleancontains(Objecto){

Iterator<E>it=iterator();

if(o==null){

while(it.hasNext())

if(it.next()==null)

returntrue;

}else{

while(it.hasNext())

if(o.equals(it.next()))

returntrue;

}

returnfalse;

}

参考资料来源:Java官网-API-Arrays

参考资料来源:Java官网-API-InterfaceList

文章到此结束,如果本次分享的java数组为什么查询快和为什么java中数组的效率比集合高的问题解决了您的问题,那么我们由衷的感到高兴!

暗格里的秘密大结局 暗格里的秘密大结局婚礼java中int类型默认值是什么 java里面的int是干什么的