Vertor、HashTable、TreeMap、Set
Vertor
- 如果初始化不指定长度,长度默认为 10
- 初始化后,数组不为空,就设置好了长度和扩容增量,ArrayList 是第一次 add ,HashMap 第一次 put 才设置长度
- 如果创建实例时没有指定扩容增量,默认每次扩容后长度变为原来的 2 倍;如果指定了增量,每次扩容后,长度变为原来的长度+增量
构造方法
// 无参构造
public Vector() {
this(10);
}
// 有参构造(参数是数组初始长度)
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
// 有参构造(参数为数组初始长度、扩容增量)
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
扩容
public synchronized boolean add(E e) {
modCount++; // 修改数次+1
ensureCapacityHelper(elementCount + 1); // 扩容,elementCount 是已保存的元素个数
elementData[elementCount++] = e; // 元素放入扩容后的数组
return true;
}
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0) // 如果原来的数组长度不够,就扩容
grow(minCapacity); // 扩容
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; // 原来的数组长度
// 这里在判断扩容增量(创建实例的时候如果指定了就用它,如果没指定,就是原来的数组长度)然后再加上原来的数组长度
int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0) // 如果扩容后的长度不够,使用 minCapacity
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) // Integer 最大值附近要专门处理,ArrayList 里见过了
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity); // 原来的数据拷贝到新的数组中
}
HashTable
-
原理 和 HashMap 基本一致,区别是 HashTable 是线程安全的,底层使用 synchronized 保证的
public synchronized V put(K key, V value) public synchronized V remove(Object key) public synchronized void putAll(Map<? extends K, ? extends V> t) public synchronized void clear() ...
-
保证安全的代价太高了,把整个数组都锁住了,所以这个玩意已经不推荐使用了
TreeMap
底层是红黑树实现的,目前还不具备这方面的能力
Set
-
子类有 HashSet、TreeSet、LinkedHashSet
-
底层通过 Map 实现,每个实例都是先 new 一个 Map,每个操作都是变相的操作这个 Map,没有 Map 就没有 Set
-
HashSet
// HashSet 构造 public HashSet() { map = new HashMap<>(); } // HashSet 添加元素,就是保存 HashMap 的 key public boolean add(E e) { return map.put(e, PRESENT)==null; }
-
LinkedHashSet
public LinkedHashSet() { super(16, .75f, true); } // 内部 new 了一个 LinkedHashMap HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
-
TreeSet
public TreeSet() { this(new TreeMap<E,Object>()); }
-
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析