超级本本降价风暴
提到hashtable,先要澄清两个问题hashCode与equals().Hashtable有容量和加载因子,容量相当于桶,因子相当于桶里的对象.而hashCode我们可以把它理解为桶的序号,所以HashCode相同的,即它们在同一个桶里,这两上对象就在同一个桶里,这时候如果他们还equals()的话,那么这两个对象就是一样的.而如果他们的hashCode不一样,即他们不在同一个桶里,那么这两个对象肯定是不一样的.
所以我们在用hashtable进行存储对象时要重写他们的hashCode与equals(),否则会出现很多重复的对象.
hashtable与hashMap最大的区别是,hashtable是方法同步的,而后者是异步的.
先来看看下面的例子吧:
public class Ball {
private int size;
private String name;
public Ball(int size, String name) {
this.size = size;
this.name = name;
}
public void setSize(int size) {
this.size = size;
}
public int getSize() {
return size;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static void main(String[] args) {
Hashtable<Ball, String> hash = new Hashtable<Ball, String>();
hash.put(new Ball(1, "one"), "1");
hash.put(new Ball(2, "two"), "2");
hash.put(new Ball(1, "one"), "1");
System.out.println(hash.size());
}
}
可能有的人会认为打印出出来的结果当然是2,有一个是重复的
但结果是3.
因为默认它们都是用Object对象来实现比较的,所以它们的hashCode当然是不一样的
我们可以加以下代码检查是否是这样
@Override
public int hashCode() {
System.out.println(super.hashCode());
return super.hashCode();
}
那么,如何才能去掉重复的对象的
这里我们必须重写hashCode,如下,我们可以把size相同的对象放入同一个桶里,再比较他们的name
把hashCode方法改为
@Override
public int hashCode() {
System.out.println(size);
return size;
}
再重写equals();
@Override
public boolean equals(Object obj) {
if (obj instanceof Ball) {
Ball ball = (Ball) obj;
return name.equals(ball.getName());
}
return false;
}
再试试,结果就是为2.
hashtable再每添加一个对象的都会先判断他们的hashCode是否一样,如果一样再判断他们是否equals(),如果返回为true的话,那么这个对象将不添加
我们也可以看一下源代码实现
/**
* Maps the specified <code>key</code> to the specified
* <code>value</code> in this hashtable. Neither the key nor the
* value can be <code>null</code>. <p>
*
* The value can be retrieved by calling the <code>get</code> method
* with a key that is equal to the original key.
*
* @param key the hashtable key
* @param value the value
* @return the previous value of the specified key in this hashtable,
* or <code>null</code> if it did not have one
* @exception NullPointerException if the key or value is
* <code>null</code>
* @see Object#equals(Object)
* @see #get(Object)
*/
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException();
}
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;//这里如果比较结果相同时就返回原来的值
}
}
modCount++;
if (count >= threshold) {
// Rehash the table if the threshold is exceeded
rehash();
tab = table;
index = (hash & 0x7FFFFFFF) % tab.length;
}
// Creates the new entry.
Entry<K,V> e = tab[index];
tab[index] = new Entry<K,V>(hash, key, value, e);
count++;
return null;
}
hashMap允许键与值为空.其他的和hashtable是一样的.
具体可再参考API...
分享到:
相关推荐
- **不支持迭代器**:与HashMap等新集合框架相比,Hashtable不支持foreach循环,使用起来不够便利。 随着Java的发展,更推荐使用ConcurrentHashMap(线程安全且性能更高)或HashMap(非线程安全但性能更好)来存储...
Hashtable类是Java Collections Framework的一部分,与HashMap有着密切的关系,但与HashMap不同的是,Hashtable是同步的,因此在多线程环境中更安全,不过这也会带来一些性能开销。 Hashtable的关键特性如下: 1. ...
HashMap与Hashtable的区别 - **同步性**:`Hashtable` 类是同步的,而 `HashMap` 不是。这意味着 `Hashtable` 可以在多线程环境中安全使用,而 `HashMap` 则不能。 - **null值的支持**:`HashMap` 允许使用 `null`...
### 提升网页游戏性能浅谈——缓冲池 在网页游戏开发的过程中,特别是在使用Actionscript 3.0开发MMORPG类网页游戏时,游戏性能往往成为开发者关注的重点。随着技术的发展,网页游戏不仅要求具备良好的视觉效果,还...
常用的实现类有HashMap、Hashtable和Properties。HashMap和TreeMap分别基于HashSet和TreeSet实现。HashMap提供了快速的键值查找,但不保证有序。TreeMap则按照键的自然顺序或Comparator进行排序。Properties是...
Map接口则用于存储键值对,包括HashMap、SortedMap(如TreeMap)以及其线程安全的实现类Hashtable。 二、集合的底层设计及其优缺点 1. List: - ArrayList:基于动态数组实现,查询速度快,增删慢,不支持并发修改...
- Hashtable:类似于HashMap,但它是线程安全的,不推荐在多线程环境中直接使用,通常使用Collections.synchronizedMap()进行同步处理。 **示例**: 在HashSet的例子中,我们创建了一个HashSet实例,然后尝试添加...
- `Hashtable`:古老且线程安全的映射实现,键和值都不允许为null,性能较差,已被`HashMap`替代。 - `HashMap`:非同步的映射实现,基于哈希表,提供快速的插入、查找和删除操作,键和值可以为null,但键是唯一的...
在Java编程语言中,`hashCode()`方法是`Object`类的一个重要成员,它用于生成对象的哈希码,这个哈希码是一个整数,通常用于优化基于哈希的集合操作,如`HashSet`、`HashMap`和`HashTable`。这些集合依赖于`hashCode...
- HashTable, HashMap, ConcurrentHashMap区别:掌握Java中不同线程安全的Map实现之间的差异。 - Equals()和HashCode()的作用:理解equals方法和hashCode方法在Java中的重要性,以及它们如何影响对象比较和集合操作...
- **Java实现浅克隆与深克隆**:浅克隆复制对象本身及含有引用的对象地址,而深克隆则复制了对象本身及所有成员变量的值。 - **枚举可以序列化吗**:枚举类型默认实现了`Serializable`接口,因此可以直接进行序列化...
此外,由于字符串的不可变性,从而可以让其 hashCode 也被缓存,在 Java 里面哈希类数据结构如 HashMap, HashTable,HashSet 其 key 用的最多的基本都是 String 类型,如此一来 key 的 hashCode 的也可以在第一次调用...
- **4.4 HashTable, HashMap, ConcurrentHashMap的区别**:探讨这三种散列表集合的设计理念、性能特点以及应用场景。 - **4.5 equals()和hashCode()的作用**:详细说明`equals()`方法与`hashCode()`方法的重要性...
- **集合类的区别**:分析了Vector, ArrayList, LinkedList的区别,以及HashTable, HashMap, ConcurrentHashMap在性能和线程安全上的区别。 - **方法重载与重写**:阐述了OverLoad与Override的区别,以及它们的定义...
- **5.5 Java实现浅克隆与深克隆:** - **浅克隆**复制对象本身及包含的引用类型成员变量,但不会复制这些引用的对象。 - **深克隆**复制对象本身及其引用的所有对象。 - **5.6 枚举可以序列化吗:** - 枚举类...