上海网站开发外包公司手机怎么制作钓鱼网站
2026/3/26 17:27:27 网站建设 项目流程
上海网站开发外包公司,手机怎么制作钓鱼网站,网站建设的毕设报告,外贸网络营销策略1. ArrayList 自动扩容机制1.1 核心扩容原理ArrayList 底层使用 Object[] 数组存储元素#xff0c;当数组容量不足时自动扩容。1.2 关键参数默认初始容量#xff1a;10扩容因子#xff1a;1.5倍#xff08;旧容量 旧容量右移1位#xff09;最大容量#xff1a;Integer.M…1. ArrayList 自动扩容机制1.1 核心扩容原理ArrayList 底层使用 Object[] 数组存储元素当数组容量不足时自动扩容。1.2 关键参数默认初始容量10扩容因子1.5倍旧容量 旧容量右移1位最大容量Integer.MAX_VALUE - 8部分VM保留头部信息1.3 源码解析// ArrayList 扩容核心方法 private void grow(int minCapacity) { int oldCapacity elementData.length; // 核心扩容算法新容量 旧容量 * 1.5 int newCapacity oldCapacity (oldCapacity 1); // 特殊情况处理 if (newCapacity - minCapacity 0) { newCapacity minCapacity; } if (newCapacity - MAX_ARRAY_SIZE 0) { newCapacity hugeCapacity(minCapacity); } // 数组复制时间复杂度 O(n) elementData Arrays.copyOf(elementData, newCapacity); } // 确定最大容量 private static int hugeCapacity(int minCapacity) { if (minCapacity 0) { // 溢出 throw new OutOfMemoryError(); } return (minCapacity MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }1.4 扩容触发时机public class ArrayListExpansion { // 1. add() 方法触发 public boolean add(E e) { ensureCapacityInternal(size 1); // 确保容量 elementData[size] e; return true; } // 2. addAll() 方法触发 public boolean addAll(Collection? extends E c) { Object[] a c.toArray(); int numNew a.length; ensureCapacityInternal(size numNew); // 确保容量 System.arraycopy(a, 0, elementData, size, numNew); size numNew; return numNew ! 0; } // 3. ensureCapacity() 手动触发 public void ensureCapacity(int minCapacity) { if (minCapacity elementData.length) { grow(minCapacity); } } }1.5 扩容过程示例public class ArrayListExpansionDemo { public static void main(String[] args) { ArrayListInteger list new ArrayList(); // 初始容量10 System.out.println(初始容量 getCapacity(list)); // 0空数组 // 添加11个元素触发扩容 for (int i 0; i 11; i) { list.add(i); if (i 10) { System.out.println(第11个元素触发扩容); System.out.println(扩容后容量 getCapacity(list)); // 15 } } // 继续添加元素 for (int i 11; i 23; i) { list.add(i); if (i 15) { System.out.println(第16个元素触发扩容); System.out.println(扩容后容量 getCapacity(list)); // 22 } if (i 22) { System.out.println(第23个元素触发扩容); System.out.println(扩容后容量 getCapacity(list)); // 33 } } } // 反射获取ArrayList实际容量仅供演示 private static int getCapacity(ArrayList? list) { try { Field field ArrayList.class.getDeclaredField(elementData); field.setAccessible(true); Object[] elementData (Object[]) field.get(list); return elementData.length; } catch (Exception e) { return -1; } } }1.6 扩容性能分析public class ArrayListPerformance { /** * 扩容时间复杂度O(n) * 涉及数组复制元素越多复制成本越高 */ public static void testAddPerformance() { int size 1000000; // 方式1不指定初始容量多次扩容 long start1 System.currentTimeMillis(); ArrayListInteger list1 new ArrayList(); for (int i 0; i size; i) { list1.add(i); } long end1 System.currentTimeMillis(); System.out.println(不指定容量耗时 (end1 - start1) ms); // 方式2指定初始容量无扩容 long start2 System.currentTimeMillis(); ArrayListInteger list2 new ArrayList(size); for (int i 0; i size; i) { list2.add(i); } long end2 System.currentTimeMillis(); System.out.println(指定容量耗时 (end2 - start2) ms); } /** * 扩容次数计算 * 10 → 15 → 22 → 33 → 49 → 73 → 109 → ... * 每次扩容复制旧数组频繁扩容影响性能 */ }2. HashMap 自动扩容机制2.1 核心扩容原理HashMap 使用数组链表/红黑树结构当元素数量超过阈值时触发扩容。2.2 关键参数默认初始容量16默认负载因子0.75扩容阈值容量 × 负载因子扩容因子2倍树化阈值链表长度 ≥ 8 且数组长度 ≥ 64链化阈值红黑树节点 ≤ 62.3 数据结构演进数组索引: [0] - 链表/红黑树 [1] - 链表/红黑树 ... [n-1] - 链表/红黑树2.4 源码解析// HashMap 扩容核心方法 final NodeK,V[] resize() { NodeK,V[] oldTab table; int oldCap (oldTab null) ? 0 : oldTab.length; int oldThr threshold; int newCap, newThr 0; // 1. 计算新容量 if (oldCap 0) { if (oldCap MAXIMUM_CAPACITY) { threshold Integer.MAX_VALUE; return oldTab; } // 核心新容量 旧容量 × 2 else if ((newCap oldCap 1) MAXIMUM_CAPACITY oldCap DEFAULT_INITIAL_CAPACITY) { newThr oldThr 1; // 新阈值也×2 } } // 2. 初始化阈值 else if (oldThr 0) { newCap oldThr; } else { newCap DEFAULT_INITIAL_CAPACITY; // 16 newThr (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); // 12 } // 3. 创建新数组 NodeK,V[] newTab (NodeK,V[])new Node[newCap]; table newTab; threshold newThr; // 4. 重新哈希rehash所有元素 if (oldTab ! null) { for (int j 0; j oldCap; j) { NodeK,V e; if ((e oldTab[j]) ! null) { oldTab[j] null; if (e.next null) { // 单个节点直接计算新位置 newTab[e.hash (newCap - 1)] e; } else if (e instanceof TreeNode) { // 红黑树处理 ((TreeNodeK,V)e).split(this, newTab, j, oldCap); } else { // 链表处理优化点 NodeK,V loHead null, loTail null; NodeK,V hiHead null, hiTail null; NodeK,V next; do { next e.next; // 关键优化无需重新计算hash只需判断新增bit位 if ((e.hash oldCap) 0) { // 位置不变 if (loTail null) loHead e; else loTail.next e; loTail e; } else { // 位置 原位置 oldCap if (hiTail null) hiHead e; else hiTail.next e; hiTail e; } } while ((e next) ! null); if (loTail ! null) { loTail.next null; newTab[j] loHead; } if (hiTail ! null) { hiTail.next null; newTab[j oldCap] hiHead; } } } } } return newTab; }2.5 扩容触发时机public class HashMapExpansion { // put() 方法中的扩容检查 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { // ... if (size threshold) { // 关键判断 resize(); } // ... } // putAll() 方法 public void putAll(Map? extends K, ? extends V m) { // 可能会触发扩容 // ... } }2.6 扩容优化高位判断/** * JDK 1.8 扩容优化无需重新计算hash * * 旧容量: 16 (10000二进制) * 新容量: 32 (100000二进制) * * 元素位置计算: hash (capacity-1) * * 扩容后元素要么在原位置要么在原位置旧容量位置 * 判断依据: (hash oldCapacity) 0 ? * * 示例 * hash 18 (10010) 15(01111) 2 * 扩容后: hash 31(11111) 18 * 由于hash的第5位(从0开始)是1所以新位置 2 16 18 */2.7 扩容过程示例public class HashMapExpansionDemo { public static void main(String[] args) { HashMapString, Integer map new HashMap(); // 初始状态 System.out.println(初始容量16阈值12); // 添加元素触发扩容 for (int i 0; i 13; i) { map.put(key i, i); if (i 12) { System.out.println(第13个元素触发扩容); // 容量变为32阈值变为24 } } // 继续添加触发二次扩容 for (int i 13; i 25; i) { map.put(key i, i); if (i 24) { System.out.println(第25个元素触发扩容); // 容量变为64阈值变为48 } } } }2.8 树化与链化public class HashMapTreeify { /** * 树化条件 * 1. 链表长度 TREEIFY_THRESHOLD(8) * 2. 数组长度 MIN_TREEIFY_CAPACITY(64) * * 链化条件 * 红黑树节点 UNTREEIFY_THRESHOLD(6) */ public static void demonstrateTreeify() { HashMapBadHashKey, Integer map new HashMap(); // 创建大量hash冲突的key for (int i 0; i 100; i) { map.put(new BadHashKey(i), i); // 当链表长度达到8且数组长度64时链表转为红黑树 } } static class BadHashKey { int value; BadHashKey(int value) { this.value value; } // 故意制造hash冲突 Override public int hashCode() { return value % 10; // 只有10个不同的hash值 } } }3. 扩容性能对比与优化3.1 性能对比表特性ArrayListHashMap扩容触发元素数量容量元素数量容量×负载因子扩容因子1.5倍2倍时间复杂度O(n) 数组复制O(n) 重新哈希空间复杂度临时需要1.5倍内存临时需要2倍内存优化策略预分配容量合适的负载因子、良好的hashCode3.2 优化建议ArrayList 优化public class ArrayListOptimization { // 1. 预分配容量最有效优化 public void optimization1() { // 已知需要10000个元素 ArrayListInteger list new ArrayList(10000); // 避免多次扩容10→15→22→33→49→73→109→... } // 2. 批量添加使用addAll public void optimization2() { ArrayListInteger list new ArrayList(); ListInteger toAdd Arrays.asList(1, 2, 3, 4, 5); // 一次性扩容到位 list.addAll(toAdd); // 只检查一次容量 // 而不是 // for (Integer i : toAdd) { // list.add(i); // 可能多次检查扩容 // } } // 3. 适时trimToSize释放内存 public void optimization3() { ArrayListInteger list new ArrayList(1000); // 添加100个元素后 list.trimToSize(); // 释放多余空间 } }HashMap 优化public class HashMapOptimization { // 1. 预分配容量考虑负载因子 public void optimization1() { // 预期存储100个元素 int expectedSize 100; float loadFactor 0.75f; // 计算初始容量 expectedSize / loadFactor 1 int initialCapacity (int) (expectedSize / loadFactor) 1; HashMapString, Integer map new HashMap(initialCapacity, loadFactor); } // 2. 使用合适的负载因子 public void optimization2() { // 读多写少降低负载因子减少哈希冲突 HashMapString, Integer readHeavyMap new HashMap(16, 0.5f); // 写多读少提高负载因子减少扩容次数 HashMapString, Integer writeHeavyMap new HashMap(16, 0.9f); } // 3. 实现良好的hashCode和equals public void optimization3() { class GoodKey { String id; Override public int hashCode() { // 良好的分布 return id.hashCode(); } Override public boolean equals(Object obj) { // 正确实现 if (this obj) return true; if (!(obj instanceof GoodKey)) return false; return id.equals(((GoodKey) obj).id); } } } // 4. 使用LinkedHashMap保持插入顺序 public void optimization4() { LinkedHashMapString, Integer map new LinkedHashMap(16, 0.75f, true) { Override protected boolean removeEldestEntry(Map.Entry eldest) { // 实现LRU缓存 return size() 100; } }; } }3.3 扩容监控与调试public class ExpansionMonitor { public static void monitorArrayList() { ArrayListInteger list new ArrayList(); // 记录扩容点 for (int i 0; i 1000; i) { int oldCapacity getCapacity(list); list.add(i); int newCapacity getCapacity(list); if (newCapacity ! oldCapacity) { System.out.printf(第%d个元素触发扩容: %d - %d%n, i 1, oldCapacity, newCapacity); } } } public static void monitorHashMap() { HashMapString, Integer map new HashMap(); // 使用反射监控内部状态 try { Field tableField HashMap.class.getDeclaredField(table); tableField.setAccessible(true); Field thresholdField HashMap.class.getDeclaredField(threshold); thresholdField.setAccessible(true); for (int i 0; i 100; i) { int oldThreshold (int) thresholdField.get(map); Object[] oldTable (Object[]) tableField.get(map); int oldCapacity oldTable null ? 0 : oldTable.length; map.put(key i, i); int newThreshold (int) thresholdField.get(map); Object[] newTable (Object[]) tableField.get(map); int newCapacity newTable null ? 0 : newTable.length; if (newCapacity ! oldCapacity) { System.out.printf(第%d个元素触发扩容: 容量 %d-%d, 阈值 %d-%d%n, i 1, oldCapacity, newCapacity, oldThreshold, newThreshold); } } } catch (Exception e) { e.printStackTrace(); } } }4. 实际应用场景4.1 高并发场景public class ConcurrentExpansion { /** * HashMap在并发扩容时可能导致死循环JDK 1.7之前 * 解决方案 * 1. 使用ConcurrentHashMap * 2. 使用Collections.synchronizedMap() * 3. 使用CopyOnWriteArrayList替代ArrayList */ // 线程安全的Map public void safeUsage() { // 方案1ConcurrentHashMap推荐 ConcurrentHashMapString, Integer concurrentMap new ConcurrentHashMap(); // 方案2同步包装 MapString, Integer synchronizedMap Collections.synchronizedMap(new HashMap()); // 方案3CopyOnWriteArrayList适合读多写少 CopyOnWriteArrayListInteger copyOnWriteList new CopyOnWriteArrayList(); } }4.2 大数据量处理public class BigDataProcessing { /** * 处理大数据时的优化策略 */ public void processLargeData() { // 场景从数据库读取100万条记录 // 错误做法频繁扩容 ArrayListRecord badList new ArrayList(); // 每次add都可能触发扩容 // 正确做法预分配分批处理 int totalRecords 1000000; int batchSize 10000; ArrayListRecord goodList new ArrayList(batchSize); for (int i 0; i totalRecords; i) { Record record fetchRecord(i); goodList.add(record); // 分批处理 if (goodList.size() batchSize) { processBatch(goodList); goodList.clear(); // 重用ArrayList // 注意clear()只清空元素不改变容量 } } } }4.3 缓存实现public class LRUCacheK, V extends LinkedHashMapK, V { private final int maxSize; public LRUCache(int maxSize) { // 设置初始容量和负载因子 super((int) (maxSize / 0.75f) 1, 0.75f, true); this.maxSize maxSize; } Override protected boolean removeEldestEntry(Map.EntryK, V eldest) { return size() maxSize; } /** * 扩容考虑 * 1. maxSize应小于初始容量×负载因子避免put时扩容 * 2. accessOrdertrue开启访问顺序 */ }5. 总结5.1 关键差异方面ArrayListHashMap扩容触发size capacitysize capacity × loadFactor扩容倍数1.5倍2倍性能影响数组复制 O(n)重新哈希 O(n)内存使用连续内存分散内存链表/树节点线程安全非线程安全非线程安全并发问题5.2 最佳实践预分配容量已知数据量时初始化时指定合适容量监控扩容大数据量时监控扩容频率优化性能合理选择结构根据使用场景选择合适的数据结构并发安全多线程环境使用线程安全版本内存优化适时释放未使用容量5.3 扩容性能公式// ArrayList 扩容次数估算 int expansions 0; int capacity 10; while (capacity requiredSize) { capacity capacity (capacity 1); // ×1.5 expansions; } // HashMap 扩容次数估算 int expansions 0; int capacity 16; while (capacity * 0.75 requiredSize) { capacity 1; // ×2 expansions; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询