HashMap集合底层实现原理
数组的特点是:寻址容易,插入和删除困难;
链表的特点是:寻址困难,插入和删除容易。
哈希表:->数组+链表组成–>线性数组
HashSet:由哈希表(实际上是一个HashMap实例)支持。无序。不允许有重复元素。HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT = new Object();。HashSet跟HashMap一样,都是一个存放链表的数组。
注意:HashSet保存的对象如果重写了equals 和 hasCode方法,会有意想不到的结果。
散列函数:
在java中,每个对象都会拥有一个hashCode()方法,
这就是散列函数,通过这个方法会返回一个32位的整数。
使用这么大的值作为散列值是为了尽量避免碰撞,
例如两个不同对象的hashCode一样的话就是碰撞了。
HashMap:里面实现一个静态内部类Entry,其重要的属性有 key , value, next
HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存在Entry[]里面。
向HashMap中添加数据 : map.put(“key”,“value”);
实质:int hashCode = key.hashCode();//key相同hashCode一定相同(没有重写hashCode的情况下)
int index = hashCode % Entry[].length;
Entry[index] = value;
从HashMap中取数据 : map.get(“key”);
实质:int hashCode = key.hashCode();
int index = hashCode % Entry[].length;
return Entry[index];
注意:
如果key相同的情况下,会覆盖上可以key所对应的value值。
Entry中的next属性就起作用了。
Entry 中 next : 指向下一个Entry。
eg:
map.put(“name”,“tom”);
//假设这次key-value 为 Entry a = “name”:“tom”;
//int index = “name”.hashCode() % Entry[].length;//假设这里的index是0
//Entry[0] = a;
map.put(“name”,“李四”);
//假设这次key-value 为 Entry b = “name”:“李四”;
//int index = “name”.hashCode() % Entry[].length;//这里的index是必然也是0
//不同的操作;b.next = a;
//Entry[0] = b;
map.put(“name”,“王五”);
//假设这次key-value 为 Entry c = “name”:“王五”;
//int index = “name”.hashCode() % Entry[].length;//这里的index是必然也是0
//不同的操作;c.next = b;
//Entry[0] = c;
如果key不相同:新加入的数据放在链头,原先加入的数据放到链尾,—> Entry[] = [ Entry_c(“name”,“王五”,“next->Entry_b”) ];
Entry_b(“name”,“李四”,“next->Entry_a”)
Entry_a(“name”,“tom”,“next”)
注解
十二.五:注解:
@Target
表示注解能写在什么上面。作用于哪里。
METHOD 可用于方法上
TYPE 可用于类或者接口上
FIELD 可用于属性上
PARAMETER 可用于参数上
CONSTRUCTOR 可用于构造方法上
ANNOTATION_TYPE 可用于注解类型上(被 @interface修饰的类型)
LOCAL_VARIABLE 可用于局部变量上
PACKAGE 用于记录java文件的package信息
@Retention 保留
定义了该Annotation被保留的时间长短
1,仅出现在源代码中,而被编译器丢弃
2,被编译在class文件中
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)
@Documented 文档API
annotation应该被作为被标注的程序成员的公共API
@Inherited 被继承的
@Inherited阐述了某个被标注的类型是被继承的
@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类
自定义注解:
public @interface A {}
给注解定义属性:
权限 参数 属性名 默认 值
public String value() default “”;
注:权限只有public 和 默认的
参数支持的数据类型:
基本数据类型
String类型
Class类型,
可以添加泛型,以及上面的数组类型。