java怎么样才能快速数字项目,java根据一个数字 怎么能快速的查询到 他在哪个A B 之间?...

匿名用户

1级

2012-03-08 回答

首先要确定你的地域信息是怎么判定的,需要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 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 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 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(key, value, null);

size = 1;

modCount++;

return null;

}

int cmp;

Entry 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 e = new Entry(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 p = getEntry(key);

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

}

final Entry 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 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;

}

追问:

您这个好像只是 HashMap和TreeMap的代码而已 而且我已经说明了 IP地址已经转变为Long类型了 根本不需要 拆分段之类的了

追答:

请问什么算法能很快的查询到?

我是要用TreeMap 还是HashMap 、数组 存放这个数据库的信息呢? 拿什么当key?

用HashMap,查询数据,直接调用get(key)就行了,不涉及到算法,JDK已经封装好了。我只是从实现上给你分析了。你应该选择HashMap。比TreeMap,数组那些快很多。,hash算法的查询是目前,最快的查询算法。你只需要用就行了。至于你说不拆分,就不拆分,我写那些是描述一种最快的底线,就是用基本类型及其封装类型。别用其它类型做Key。

追问:

就是map里存放的是ip地址段 不是准确的地址 我给一个地址要的是比大小 而不可能直接 get(“ip”) 就能得到。 我所求的算法最简单的比如 将startIp放到treeMap的key中 for循环遍历整个map比较大小 找到比要搜索的ip地址小的最大的key(不太会表达有点绕) 然后取得他的值;稍微好点的像二分查找。其他还有什么快速的算法 我都不算太清楚 因为不知道是不是适合 所以想请各位帮忙解答下,争取找到最优的 因为查询是千万次的

追答:

我能不能理解为?先找,如果找到,就返回,找不到,就遍历,这个元素的上一个和下一个在哪,就是找到和他最近的?

如果要找出元素,HashMap是最快的,如果要找到元素最近的一个,那只有TreeMap才有现成的方法。而且效率肯定比自己写的算法,效率要高。

这样,你涉及到一个取舍。

1、如果做为要找的数据,在查询时大多时候都可以找到的情况下,用HashMap。

2、如果要找的数据,在查询时大多时候都找不到的情况下,用TreeMap。

取舍要凭自己的数据量,访问流来决定。其实,用什么,主要是分析所有影响因素。来做评估。任何事,都有利有弊。以下还有种作法,可贡参考。

当然,还有种作法,以空间换时间,就是用内存,换效率。维护两个Map,两个Map中的元素,保持一至。首先在HashMap中找,用map.get(key),找不到,那就在TreeMap中找,map. lowerEntry(K key),或者map.higherEntry(K key).这两个方法可以找到上一个、下一个元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值