Day 18
Set接口:
1. 无序(添加和取出的顺序不同),没有索引, 但是取出的顺序是固定的
2. 不允许有重复的元素,可以包含一个null
常用方法:
因为set接口也实现了collection接口,所以和collection接口的方法一样
遍历方式:
1.iterator
2.增强for
3.因为没有索引,所以不能用普通for
HashSet:
HashSet底层是HashMap;
hashset.add(new Dog("tom"));
hashset.add(new Dog("tom")); //可以添加
hashset.add(new String("hsp"));
hashset.add(new String("hsp")); //无法添加
HashMap的底层是 数组+链表+红黑树
当hashset添加元素时,先得到hash值,之后转成table 中的 索引值
查看这个 table[index] 位置上有没有元素,
如果没有,直接加入,
如果有,调用equals方法(考虑是否被重写),如果相同则放弃添加,如果不同就添加到该位置上的链表的末尾
如果一条链表的个数到达TREEIFY_THRESHOLD( 默认是8 ), 并且 table 大小 >= MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树TreeNode)
HashSet 的 扩容 和 转红黑树 机制
1. 第一次添加时,table数组扩容到16, 临界值 16 * 0.75(loadFactor 加载因子) = 12;
2. 当table数组使用到了12个时,就会扩容2倍(16 * 2),新的临界值就是 32 * 0.75 = 24,以此类推;
3. 如果一条链表的个数到达TREEIFY_THRESHOLD( 默认是8 ), 并且 table 大小 >= MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树);
如果一条链表的个数达到8个,但是table大小没到64, 那么就仍然采用数组扩容机制。
LinkedHashSet:
继承HashSet, 实现Set接口
LinkedHashSet 底层是 LinkedHashMap, 底层维护一个数组和双向链表
LinkedHashSet 加入顺序和取出顺序相同
第一次添加时,table[] 数组直接扩容到16,数组类型是 HashMap$Node; 存放的节点类型是 LinkedHashMap$Entry
Treeset:
底层是Treemap
1.当使用无参构造器创建对象时,是无序的!
2. 使用带有comparator参数的构造器,可以实现排序
Treeset treeset = new Treeset(new comparator(){
public int compare(Object o1, Object o2){
return ((String) o1).compareTo((String) 02);
}
})
Map:

Map 和 Collection 是同级的,Collection是单列集合, Map是双列集合(保存的是key-value 键值对)
HashMap:
是无序的
Map中的key和value可以是任意引用类型的数据,会封装到HashMap$Node对象中
Map中的key不允许重复,如果key相同,相当于替换
Map中的key 和 value 都可以为 null, 但key只能有一个null
通常用String作为map的key,不是必须,只要是Object子类都可以
key 和 value之间存在一对一关系,即通过key总能找到对应的value
map.get(key); //返回对应的value
Map接口的常用方法:

1. map.put();
2. map.remove();
3. map.get();
4. map.size();
5. map.isEmpty();
6. map.clear();
7. map.containsKey();
8. map.containsValue();
9. map.keySet();
HashTable: Map接口的实现子类, 和hashmap是平级的关系
存放的元素是 key-value
key 和 value都不能为null,否则抛出空指针异常
hashtable是线程安全的,hashmap是线程不安全的
hashtable底层维护一个 Hashtable$Entry[] 初始化大小为11, 临界值threshold = 11 * 0.75 = 8;(超过8个才扩容)
扩容机制: 向左位移一位( *2) + 1;
Treemap:
使用默认构造器创建对象时,是无序的
Properties: Hashtable 的 子类,间接实现了Map接口
key和value不能为null
存取顺序不同
properties 通常用于从 配置文件 xxx.properties 文件中,加载数据到Properties对象中,并进行读取和修改
properties.put(key, value);
properties.remove( key);
properties.get(key);
properties.getProperties(key);
如何选择集合实现类:
1: 先判断 存储类型( 一组对象, 一组键值对)
2: 一组对象(单列集合): Collection接口
允许重复: List
增删多:LinkedList(底层是双向链表)
改查多:ArrayList(Object类型的可变数组)
不允许重复:Set
无序:Hashset(底层是hashmap,即:数组+链表+红黑树)
排序:TreeSet
3.一组键值对(双列集合):Map接口
键无序:Hashmap(底层是 数组+链表+红黑树)
键排序:Treemap
键插入和取出顺序一致:LinkedHashMap
读取文件:Properties
Collections 工具类:
Collections.reverse( List );
Collections.shuffle( List );
Collections.sort( List ); //自然排序, 默认生序
Collections.sort( List, comparator);
Collections.swap( List, index1, index2 );
Collections.max( List ); //根据自然排序,返回最大元素
Collections.max( List, comparator);
Collections.frequency( List, value ); //返回value在list中出现的次数
Collections.copy( dest, source ); // 注意! 使用该方法前,必须先给dest赋值,个数和source的长度一样。
Collections.replaceAll( list, oldVal, newVal ); //用newVal替换oldVal

浙公网安备 33010602011771号