关于Java中HashMap和HashSet

来源:互联网 发布:网络金融销售是诈骗吗? 编辑:程序博客网 时间:2024/04/28 14:22

HashMap:存储形式key-value,它并不是线程安全的。初始容量:一般是16,加载因子:一般0.75,至于这两个概念,就不多说了。当数据量达到当前容量*加载因子,容量就是成倍扩展。

HashSet: 存储形式就是一个对象了,不是线程安全的。初始容量:一般是16,加载因子:一般0.75


再说HashMap存储形式,我就语言描述了,不对之后,还望您指正。

比如我们进行下面的步骤:

Map<Integer,String> worker = new HashMap<Integer,String>();worker.put(1, "张三");worker.put(2, "李四");

Java的装箱拆箱我就不说了。当向map中插入数据的时候,先计算key的Hash值,假如hash到map的对应位置发现这个位置为null,则可以把此对象存入到这次,当然只是一个指向此对象的链接。如果此处不是null,也就是它hash后的位置被被人占据了,那么它就要和这个占据着者比较一下了,如果key是相同的,那么就把占据着的value改成自己的,如果key不是相同的,那么就默默地自己搞个链接也指向自己,这样从map中也能找到自己。

比如:

Map<Integer,String> worker = new HashMap<Integer,String>();worker.put(1, "张三");worker.put(1, "李四");System.out.println(worker.get(1));

此时会打印出李四。这个我们就不奇怪了。

再看取元素,如果get时候拿到的key进行同样方法的hash之后找不到对象,当然就返回null,如果找到一个这个位置有对象,那么就和他比较一下,key相同就返回,不相同就比较此处链接的其他对象,实在都不相同,那就返回null;


关于HashSet,它底层用的是HashMap,它存入的值被用成HashMap的key,至于map的value,value 则存储了一个 PRESENT,它是一个静态的 Object 对象。(这个我木有研究过,有了解的希望不吝赐教,先在此谢过~~)。其余的存取就和HashMap一样了。

下面搞个例子试试:

public class Test {public static void main(String [] args){Set<Name> mySet = new HashSet<Name>();Name name1 = new Name("张","三");Name name2 = new Name("张","三");mySet.add(name1);mySet.add(name2);System.out.println(mySet);}}class Name{private String first;private String last;public Name(String f,String l){this.first  = f;this.last = l;}@Overridepublic String toString() {return "first:"+this.first+";last:"+this.last;}}
这个会输入两个“张三”,都能成功,输出就是:[first:张;last:三, first:张;last:三]。

那不是Hash算法重写以后呢?再看:


public class Test {public static void main(String [] args){Set<Name> mySet = new HashSet<Name>();Name name1 = new Name("张","三");Name name2 = new Name("张","三");mySet.add(name1);mySet.add(name2);System.out.println(mySet);}}class Name{private String first;private String last;public Name(String f,String l){this.first  = f;this.last = l;}@Overridepublic int hashCode() {return this.first.hashCode();}@Overridepublic String toString() {return "first:"+this.first+";last:"+this.last;}}
这样总会只进去一个了吧,但是输出结果:[first:张;last:三, first:张;last:三]

那,equals方法重写,再看:

public class Test {public static void main(String [] args){Set<Name> mySet = new HashSet<Name>();Name name1 = new Name("张","三");Name name2 = new Name("张","三");mySet.add(name1);mySet.add(name2);System.out.println(mySet);}}class Name{private String first;private String last;public Name(String f,String l){this.first  = f;this.last = l;}public boolean equals(Object n){if(this==n)return true;if(n.getClass() == Name.class){Name nn = (Name)n;return nn.first.equals(this.first) && nn.last.equals(this.last);}return false;}@Overridepublic int hashCode() {return this.first.hashCode();}@Overridepublic String toString() {return "first:"+this.first+";last:"+this.last;}}
这次结果是:[first:张;last:三],我们才明白HashSet在进行存储时候Hash方法和对象自己的方法hashCode,进行比较和对象自己的equals方法是有关系的。那每个对象都有的方法有几个呢,看下面:

protected Object clone() throws CloneNotSupportedException{}protected void finalize() throws Throwable {}public int hashCode() {}public String toString() {}public boolean equals(Object obj) {}

貌似这个问题面试常问,哈哈~~


希望您能有收获,本人能力有限,如果哪里有学的不到的地方,望您不吝赐教,先在此谢过~~

最后,这篇文章不错,李刚老师发表的:

点击打开链接









0 0
原创粉丝点击