hashmap hashtable hashset和map的区别
面试可能会遇到,这里参考别人的回答总结一下:
概念:
map接口中,键和值一一对应,可以通过键来获取值。
- 给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值。
- 当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常.
- 当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常。
- 当在不允许使用Null对象的Map中使用Null对象,会抛出一个NullPointerException 异常。
- 当尝试修改一个只读的Map时,会抛出一个UnsupportedOperationException异常
clear()、containsKey(Object k)、containsValue(Object v)、entrySet()、equal()、 get()、hashCode()、isEmpty()、 keySet()、 put(Object k,Object k)、putAll(Map m)、remove(Object k)、size()、Collection values()
mport java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
Map m1 = new HashMap();
m1.put("Zara", "8");
m1.put("Mahnaz", "31");
m1.put("Ayan", "12");
m1.put("Daisy", "14");
System.out.println();
System.out.println(" Map Elements");
System.out.print("\t" + m1);
}
}
编译结果:
Map Elements
{Mahnaz=31,Ayan=12,Daisy=14,Zara=8}
Hashtable在哈希表中存储键值对,当时用一个哈希表,要指定用作键的对象,以及要链接到该键的值,然后该键通过哈希处理,所得到的散列码被用作存储在该表中值得索引。有四种构造方法Hashtable() Hashtable(int size) Hashtable(int size,float fillRatio) Hashtable(Map m)
clear()、clone()、containsKey(Object k)、containsValue(Object v)、Enumerationelements()、 get()、isEmpty()、 keys()、 put(Object k,Object value)、rehash()、remove(Object k)、size()、toString()
import java.util.*;
public class HashTableDemo {
public static void main(String args[]) {
// Create a hash map
Hashtable balance = new Hashtable();
Enumeration names;
String str;
double bal;
balance.put("Zara", new Double(3434.34));
balance.put("Mahnaz", new Double(123.22));
balance.put("Ayan", new Double(1378.00));
balance.put("Daisy", new Double(99.22));
balance.put("Qadir", new Double(-19.08));
// Show all balances in hash table.
names = balance.keys();
while(names.hasMoreElements()) {
str = (String) names.nextElement();
System.out.println(str + ": " +
balance.get(str));
}
System.out.println();
// Deposit 1,000 into Zara's account
bal = ((Double)balance.get("Zara")).doubleValue();
balance.put("Zara", new Double(bal+1000));
System.out.println("Zara's new balance: " +
balance.get("Zara"));
}
}
编译结果:
Qadir:-19.08
Zara:3434.34
Mahnaz:123.22
Daisy:99.22
Ayan:1378.0
Zara's new balance:4434.34
hashMap是基于哈希表的Map接口的非同步实现,此实现提供所有可先的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是他不保证该顺序恒久不变。hashmap实际上是一个“链表散列”的数据结构、即数组和链表的结合体.
简单的来说,hashmap在底层将key-value当成一个整体来处理,这个整体就是一个entry对象,hashmap底层采用一个entry[]数组来保存所有的keu-value对,当需要存储一个entry对象时,会根据hash算法。来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个entry时i,也会根据hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出entry。原文地址:http://wiki.jikexueyuan.com/project/java-collection/hashmap.html、
对于查找,添加等操作很快,仅需一次寻址即可,如果定位到的数组不含链表,对于添加查找操作操作很快,无序遍历。如果含有链表,需要先遍历链表,存在即覆盖,否则新增。对于查找操作,仍需遍历链表,然后通过key对象的equals方法逐一对比查找。所以,性能考虑,链表越少越好。 (这个hashmap有点麻烦啊)原文:https://www.cnblogs.com/chengxiao/p/6059914.html
hashset主要用来设计高性能及运算的,例如对两个集合求交集、并集、差集等。集合中包含一组不重复出现切勿特性顺兴的元素。原文http://www.cnblogs.com/kissdodog/archive/2013/02/02/2889887.html
1. hashset中的值不能重复且没有顺序
2. 容量会按需自动添加
static void Main(string[] args)
{
HashSet<string> hs = new HashSet<string>();
hs.Add("你");
hs.Add("好");
hs.Add("吗");
HashSet<string> hs1 = new HashSet<string>();
hs1.Add("你");
hs1.Add("好");
bool b = hs1.IsProperSubsetOf(hs); //确定hs1是否是hs的真子集
Console.WriteLine(b); //输出True
HashSet<string> hs2 = new HashSet<string>();
hs2.Add("爱你");
IEnumerable<string> list = hs.Union(hs2); //返回并集
foreach (string str in list)
{
Console.WriteLine(str); //输出 你 好 吗 爱你
}
Console.ReadKey();
}
区别:
继承的父类不同:
hashtable继承dictionary类,hashmap继承abstractmap类,但两者都实现了map接口
public class HashTable<K,V> extends Dictionary<K,V>
implement Map<K,V>,Cloneable, Serializable
public class HashMap<K,V> extends AbstractMap<K,V>
implement Map<K,V>,Cloneable,Serializable
线程安全性不同:
hashTable中的方法是synchronized的,而hashmap中的方法在缺省情况下是非synchronized的。
是否提供contains方法:
hashmap去掉了contains方法,改成了containsKey方法和containsValue方法,hashtable保留了contains,containsValue和containsKey方法,其中contains和containsValue功能相同。
key和value是否允许null值:
hashtable中都不允许出现null值,hashmap中,null可以作为主键;可以有一个或多个键所对应的值为null。当get()返回null时,可能是没有这个主键,也有可能是对应的值为null,所以只能用containsKey()来判断是否存在某个键。(这个面试官喜欢问)
哈希值的计算方法不同,hashtable直接使用的是对象的hashcode,而hashmap则是在hashcode的基础上进行了一些变化。
//Hashtable中可以看出的是直接采用关键字的hashcode作为哈希值
int hash = key.hashCode();
//然后进行模运算,求出所在哗然表的位置
int index = (hash & 0x7FFFFFFF) % tab.length;
//HashMap中的实现
//这两行代码的意思是先计算hashcode,然后再求其在哈希表的相应位置
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
//求位于哈希表中的位置
static int indexFor(int h, int length) {
return h & (length-1);
}
内部实现使用的数组初始化和扩容方式不同,内存初始化大小不同。hashtable的初始大小是11,hashmao初始大小是16
hashmap和hashset的区别
hashmao是map的一个实现类,hashset是set的一个实现类,同时,hahsmao是hashset的一个替代品,
hashset以对象为元素,hashmap以一组对象(key-value)为元素,前者拒绝接受重复的对象,后者可以看错三个视图。key的set,value的collection,entry的set,这里hashset就是hashmap的一个视图。
hashset就是使用hashmap实现的,和hashmap不同的是它不需要key和value两个值,往hashset里面插入对象其实就是
public boolean add(object o){
return map.put(o,PRESENT)==null;
}
java中的集合 | 有序 | 允许元素重复 | |
collection | 否 | 是 | |
list | |||
set | abstractSet | 否 | 否 |
hashSet | |||
treeSet | 是 | ||
map | abstractMap | 否 | 使用key-value来映射和存储数据,key必须唯一,value可以重复 |
hashMap | |||
TreeMap | 是 |
父类 | 线程安全性 | 是否提供contains方法 |
是否允许null值 |
遍历方式 | 初始大小 | |
hashtable | distionary | synchronized | 否(containKey和containValue) | 否 | Iterator、Enumeration |
11、old *2+1 |
hashmap | abstractmap | 非synchronized | 是(containsKey、containsValue、contains) | 是 | Iterator | 16、2的指数 |
hashSet | set的实现类 | |||||
hashMap |
map的实现类 |
上一篇: EL表达式隐式对象
推荐阅读
-
Java中HashMap和TreeMap的区别深入理解
-
详解Java中HashSet和TreeSet的区别
-
java中Hashtable和HashMap的区别分析
-
HashTable、HashSet和Dictionary的区别点总结
-
HashMap和Hashtable的详细区别
-
Java中HashMap和TreeMap的区别深入理解
-
Java自学-集合框架 HashMap和Hashtable的区别
-
对python内置map和six.moves.map的区别详解
-
JS forEach和map方法的用法与区别分析
-
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作