1.Set接口:
特点: --无序【添加和取出的顺序不一致】,没有索引 --不允许重复元素,所以最多包含一个null --和 List 接口一样, Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样。
–HashSet
特点: --HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。 --HashSet 允许有 null 值。 --HashSet 是无序的,即不会记录插入的顺序。 --HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。 --HashSet 实现了 Set 接口。 --HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。
常见方法:
–TreeSet:
特点: --TreeSet 是二叉树实现的,Treeset中的数据是自动排好序的,不允许放入null值。 --HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。 --HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。
TreeSet常见方法:
add(E e) // 如果不存在,则添加。 clear() //清空 contains(Object o)//查询指定元素是否存在,存在返回true isEmpty() // 判空 iterator() //返回此容器的迭代器 remove // 如果指定元素在此set中则移除 size() //返回元素数量
2.Map接口:
特点: --Map与Collection并列存在。用于保存具有映射关系的数据:key-value --Map 中的key 和value 都可以是任何引用类型的数据 --Map 中的key 用Set来存放,不允许重复,即同一个Map 对象所对应的类,须重写hashCode()和equals()方法 --常用String类作为Map的“键” --key 和value 之间存在单向一对一关系,即通过指定的key 总能找到唯一的、确定的value --Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和Properties。 --HashMap 是Map 接口使用频率最高的实现类
–哈希表:
哈希表(HashTable,散列表)是根据key-value进行访问的数据结构,他是通过把key映射到表中的一个位置来访问记录,加快查找的速度,其中映射的函数叫做散列函数,存放记录的数组叫做散列表,哈希表的主干是数组
–HashMap:
--它是一个标准的哈希表 --JDK8之前,HashMap:整体结构是一个"数组 + 链表" 结构 --JDK8之后,HashMap:整体结构是一个"数组 + 链表 + 红黑树" 结构
–HashMap的构造方法
//1.指定容量和负载因子 public HashMap(int initialCapacity, float loadFactor) { //判断初始容量是否合法 if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity); //判断初始容量是否大于最大容量,如果大于则初始化为最大容量 1 << 30 if (initialCapacity > MAXIMUM_CAPACITY) initialCapacity = MAXIMUM_CAPACITY; //判断装载因子是否合法 //isNan()方法判断是否为数字 if (loadFactor <= 0 || Float.isNaN(loadFactor)) throw new IllegalArgumentException("Illegal load factor: " + loadFactor); this.loadFactor = loadFactor; //计算扩容门槛 this.threshold = tableSizeFor(inistialCapacity); } //2.仅指定容量,使用默认的负载因子,内部实现实际上还是依赖的第一种方法 public HashMap(int initialCapacity) { this(initialCapacity, DEFAULT_LOAD_FACTOR); } //3.使用默认容量和负载因子 public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR); table = new Entry[DEFAULT_INITIAL_CAPACITY]; init(); } //4.根据指定的map初始化,根据指定的map的容量和默认容量共同决定初始化容量,使用默认负载因子 public HashMap(Map extends K, ? extends V> m) { this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); putAllForCreate(m); }
–HashMap的put( K key,V value)方法:
1、首先会将key进行hash运算,如果为null,则hash值为0,否则 返回key的hashcode()的值(注意:该值会进行高低位异或运算) 目的是key的高低位二进制数据都参与到运算中来,是的key的 hash值足够散列(不要让key都插入到一个节点中) 2、添加节点: 如果数组没有初始化同时长度为0 如果是第一次添加节点,则容量是16,负载因子是0.75,触发扩容的阈值:12。 3、插入时,求插入key的下标 获取hashcode值,求模元素 (hash % length <===> (length - 1) & hash )