java数组为什么查询快 为什么java中数组的效率比集合高
各位老铁们好,相信很多人对java数组为什么查询快都不是特别的了解,因此呢,今天就来为大家分享下关于java数组为什么查询快以及为什么java中数组的效率比集合高的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
java中ArrayList为什么比LinkedList查询速度快
因为ArrayList是以数组的方式储存的,得到数据直接用下标就可以了,删除也直接根据下标就删除了,用ArrayList查询时最快的;而LinkedList是以双向链表的形式储存的,删除和增加数据速度快,只要把两边的指向变化就可以了。而ArrayList删除和增加数据都涉及到数据的移动问题,相对而言慢点。
为什么java中数组的效率比集合高
list集合的遍历3种方法:
[java] view plaincopy
package com.sort;
import java.util.ArrayList;
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中数组的效率比集合高的问题解决了您的问题,那么我们由衷的感到高兴!