Java HashMap LinkedHashMap 区别及原理

HashMap原理 HashMap是Map的一个常用的子类实现。其实使用散列算法实现的。 HashMap内部维护着一个散列数组(就是一个存放元素的数组),我们称其为散列桶,而当我们向HashMap中存入一组键值对时,HashMap首先获取key这个对象的hashcode()方法的返回值,然后使用该值进行一个散列算法,得出一个数字,这个数字就是这组键值对要存入散列数组中的下标位置。 那么得知了下标位置后,HashMap还会查看散列数组当前位置是否包含该元素。(这里要注意的是,散列数组中每个元素并非是直接存储键值对的,而是存入了一个链表,这个链表中的每个节点才是真实保存这组键值对的。)检查是否包含该元素时根据当前要存入的key在当前散列数组对应位置中的链表里是否已经包含这个key,若不包含则将这组键值对存入链表,否则就替换value。 那么在获取元素时,HashMap同样先根据key的hashcode值进行散列算法,找到它在散列数组中的位置,然后遍历该位置的链表,找到该key所对应的value之后返回。 看到这里可能有个疑问,链表中应该只能存入一个元素,那么HashMap是如何将key-value存入链表的某个节点的呢?实际上,HashMap会将每组键值对封装为一个Entry的实例,然后将该实例存入链表。 如图所示:

HashMap的存取是依赖于key的hashcode方法的返回值的,而hashcode方法实际上是在Object中定义的。其定义如下: int hashCode() 代码如下:

public class HashMapDemo {(String[] args) {Map<String, Integer> hashMap = new HashMap<String,Integer>();hashMap.put(“one”, 1);hashMap.put(“two”, 2);hashMap.put(“three”, 3);hashMap.put(“four”, 4);hashMap.put(“five”, 5);hashMap.put(“six”, null);//遍历Map中的key的hashMapfor(String str : hashMap.keySet()) {System.out.println(str +”:”+ str.hashCode() );}}}

运行结果: six:113890 four:3149094 one:110182 two:115276 three:110339486 five:3143346

遍历每一组键值对 Set

public class HashMapDemo {(String[] args) {Map<String, Integer> hashMap = new HashMap<String,Integer>();hashMap.put(“one”, 1);hashMap.put(“two”, 2);hashMap.put(“three”, 3);hashMap.put(“four”, 4);hashMap.put(“five”, 5);hashMap.put(“six”, null);//遍历键值对Set<Entry<String, Integer>> set = hashMap.entrySet();for(Entry<String, Integer> e : set) {System.out.print(“key:”+e.getKey()+”\t”);System.out.println(“value:”+e.getValue());}}}

运行结果: key:six value:null key:four value:4 key:one value:1 key:two value:2 key:three value:3 key:five value:5

重写一个类的hashcode()方法有以下注意事项: 1、若一个类重写了equals方法,那么就应当重写hashcode()方法。 2、若两个对象的equals方法比较为true,那么它们应当具有相同的hashcode值。 3、对于同一个对象而言,在内容没有发生改变的情况下,多次调用hashCode()方法应当总是返回相同的值。 4、对于两个对象equals比较为false的,并不要求其hashcode值一定不同,但是应尽量保证不同,这样可以提高散列表性能。

代码如下:

{(String[] args) {Map<Card, Person> map = new HashMap<Card, Person>();Person p1 = new Person(new Card(“001″),”张三”);Person p2 = new Person(new Card(“002″),”李四”);map.put(p1.getCard(), p1);map.put(p2.getCard(), p2);System.out.println(“HashMap 中存放的人员信息:\n”+map);//张三改名为张山,,身份证号不变。 Person p3 = new Person(new Card(“001″),”张山”);map.put(p3.getCard(), p3);System.out.println(“张三改名为张山后 HashMap 中存放的人员信息:\n”+map);//查找身份证为001 的人员信息 System.out.println(“查找身份证为:001 的人员信息:”+map.get(new Card(“001”)));}}class Card {private final String IdCard;public Card(String idCard) {super();IdCard = idCard;}public String getIdCard() {return IdCard;}() {final int prime = 31;int result = 1;result = prime * result + ((IdCard == null) ? 0 : IdCard.hashCode());return result;}(Object obj) {// 如果地址一样,则两个对象相同 if (this == obj) {return true;}(obj instanceof Card) {Card card = (Card)obj;return card.IdCard .equals(this.IdCard);}return false;}@Overridepublic String toString() {return “Card [IdCard=” + IdCard + “]”;}}class Person {private Card card;private String name;() {final int prime = 31;int result = 1;result = prime * result + ((card == null) ? 0 : card.hashCode());result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}/*** 重写equals()方法 当两个人得身份证号相同以及姓名相同时,表示这两个人是同一个人。*/(Object obj) {if (obj == this) {return true;}if (obj instanceof Person) {Person p = (Person) obj;return this.card.equals(p.card) && this.name.equals(p.name);}return false;}public Person(Card card, String name) {super();this.card = card;this.name = name;}public Card getCard() {return card;}(Card card) {this.card = card;}public String getName() {return name;}(String name) {this.name = name;}@Overridepublic String toString() {return “Person [name=” + name + “]”;}}有我们特有的记忆,亲情之忆友谊之花爱情之树以及遗憾之泪!

Java HashMap LinkedHashMap 区别及原理

相关文章:

你感兴趣的文章:

标签云: