当前位置: 首页 > news >正文

网站后台验证码出不来百度关键词自然排名优化公司

网站后台验证码出不来,百度关键词自然排名优化公司,有需要网站建设的没,wordpress 二次元插件目录 一、ArrayList:动态数组的扩容与视图陷阱​ (一)初始容量与扩容机制:为什么默认大小是 10?​ (二)subList 的 “视图特性”:修改子列表为何影响原列表?​ 二、H…

目录

一、ArrayList:动态数组的扩容与视图陷阱​

(一)初始容量与扩容机制:为什么默认大小是 10?​

(二)subList 的 “视图特性”:修改子列表为何影响原列表?​

二、HashMap:哈希表的进化与红黑树的登场​

(一)数据结构:从链表到红黑树的转换​

(二)哈希冲突与负载因子:0.75 的奥秘​

(三)key 为何要重写 hashCode 和 equals?​

三、集合线程安全:从 Vector 到 CopyOnWriteArrayList​

(一)Vector 与 ArrayList:同步方法的性能代价​

(二)Collections.synchronizedList:简单包装的同步集合​

(三)CopyOnWriteArrayList:读写分离的高性能方案​

四、实践对比:百万级数据下的性能测试​

(一)测试代码(核心片段)

(二)测试结果(100 万条数据)

(三)结论​

总结:根据场景选择合适的集合​


Java 集合框架是日常开发中频繁使用的工具,但多数开发者停留在 “会用” 的层面,对其底层原理知之甚少。本文将深入剖析 ArrayList、HashMap 等核心集合的设计逻辑,揭秘线程安全集合的实现细节,并通过百万级数据测试验证理论,带你从 “会用” 进阶到 “懂原理”。

一、ArrayList:动态数组的扩容与视图陷阱​

ArrayList 作为最常用的 List 实现类,底层基于动态数组实现,但它的 “动态” 背后藏着精巧的设计。​

(一)初始容量与扩容机制:为什么默认大小是 10?​

ArrayList 的无参构造器会初始化一个空数组,首次添加元素时才会扩容至 10(这是 Java 设计者基于常见场景的经验值)。当元素数量超过当前容量时,扩容逻辑如下(JDK 1.8 源码):

private void grow(int minCapacity) {int oldCapacity = elementData.length;// 扩容 1.5 倍:oldCapacity + oldCapacity/2int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;// 复制原数组元素到新数组elementData = Arrays.copyOf(elementData, newCapacity);
}
  • 1.5 倍扩容的原因:若扩容倍数太大(如 2 倍),会浪费内存;若太小(如 1.2 倍),则需频繁扩容,触发多次数组复制(Arrays.copyOf 是耗时操作)。1.5 倍是时间与空间的平衡。​
  • 注意:通过 ArrayList(int initialCapacity) 构造器指定初始容量,可减少高频添加场景下的扩容次数(如已知需存储 1000 条数据,直接初始化容量为 1000)。

(二)subList 的 “视图特性”:修改子列表为何影响原列表?​

subList(int fromIndex, int toIndex) 方法返回的是原列表的视图(内部类 SubList 实例),而非新列表。它与原列表共享底层数组,只是通过偏移量限制了访问范围:

List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5));
List<Integer> subList = list.subList(1, 3); // [2,3]subList.add(6); 
System.out.println(list); // [1,2,3,6,4,5](原列表被修改)
  • 风险点:若原列表被结构性修改(如 add、remove 导致数组扩容或收缩),子列表会抛出 ConcurrentModificationException。​
  • 正确用法:若需独立子列表,应通过 new ArrayList<>(subList) 包装。

二、HashMap:哈希表的进化与红黑树的登场​

JDK 1.8 对 HashMap 进行了重大优化,引入红黑树解决链表过长的性能问题,其底层结构变为 “数组 + 链表 + 红黑树”。​

(一)数据结构:从链表到红黑树的转换​

  • 数组(桶):默认初始容量 16(必须是 2 的幂,便于通过 (n - 1) & hash 计算索引),每个元素是链表或红黑树的头节点。​
  • 链表:当多个 key 计算出相同索引(哈希冲突)时,元素以链表形式存储。​
  • 红黑树:当链表长度超过 8 且数组容量 ≥ 64 时,链表会转为红黑树(查询时间复杂度从 O (n) 降至 O (log n));当树节点少于 6 时,会退化为链表(避免树结构的维护成本)。​

(二)哈希冲突与负载因子:0.75 的奥秘​

  • 哈希冲突解决:通过 (n - 1) & hash 计算索引(等价于 hash % n,但位运算更快),冲突时采用 “链地址法”(链表 / 红黑树存储冲突元素)。​
  • 负载因子(0.75):当元素数量(size)≥ 容量 × 负载因子时,触发扩容(容量翻倍)。0.75 是基于 “泊松分布” 的设计:既避免了容量过小导致的频繁扩容,又减少了容量过大造成的内存浪费。实验表明,此时链表长度为 8 的概率仅为 0.00000006。​

(三)key 为何要重写 hashCode 和 equals?​

HashMap 判断 key 相等的逻辑是:​

  1. 先比较 hashCode 是否相等(相同对象必须有相同哈希码)。​
  2. 再通过 equals 验证内容是否相等(哈希码相同的对象不一定相等,即 “哈希碰撞”)。

若 key 是自定义对象却未重写这两个方法,会导致:​

  • hashCode 不重写:相同内容的对象可能计算出不同哈希码,被视为不同 key。​
  • equals 不重写:默认比较地址,导致相同内容的对象被视为不同 key。​

正确示例:

class User {String id;// 重写 hashCode(结合关键字段)@Overridepublic int hashCode() { return Objects.hash(id); }// 重写 equals(判断内容相等)@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(id, user.id);}
}

三、集合线程安全:从 Vector 到 CopyOnWriteArrayList​

ArrayList、HashMap 都是线程不安全的(多线程修改可能导致数据错乱),线程安全的集合方案各有优劣。​

(一)Vector 与 ArrayList:同步方法的性能代价​

  • Vector:所有方法(如 add、get)都被 synchronized 修饰,通过全量同步保证线程安全,但多线程竞争时会导致大量锁等待,性能较差。​
  • ArrayList:无同步机制,线程不安全,但性能更高。​

结论:Vector 已被淘汰,仅在遗留系统中可见。​

(二)Collections.synchronizedList:简单包装的同步集合​

Collections.synchronizedList(list) 会返回一个包装类,其核心是通过同步代码块包裹所有方法:

public E get(int index) {synchronized (mutex) { // mutex 是内部锁对象return list.get(index);}
}
  • 优势:使用简单,适用于轻量并发场景。​
  • 缺陷:迭代操作仍需手动加锁(否则可能抛出 ConcurrentModificationException),且锁粒度大(整个集合),高并发下性能不佳。​

(三)CopyOnWriteArrayList:读写分离的高性能方案​

CopyOnWriteArrayList 是 JUC 包提供的线程安全集合,核心思想是 “写时复制”:​

  • 读操作:直接读取当前数组,无需加锁(弱一致性,可能读取到旧数据)。​
  • 写操作:复制一份新数组,修改后替换原数组,通过 ReentrantLock 保证同步。
public boolean add(E e) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;// 复制新数组Object[] newElements = Arrays.copyOf(elements, len + 1);newElements[len] = e;setArray(newElements); // 替换原数组return true;} finally {lock.unlock();}
}
  • 优势:读操作无锁,适合读多写少的高并发场景(如配置缓存、白名单)。​
  • 缺陷:写操作复制数组会消耗内存,且无法保证实时一致性。

四、实践对比:百万级数据下的性能测试​

为验证理论,我们通过代码测试不同集合在百万级数据下的增删查性能(测试环境:JDK 11,8C16G 服务器)。​

(一)测试代码(核心片段)

// 测试添加性能
public static void testAdd(List<Integer> list, int size) {long start = System.currentTimeMillis();for (int i = 0; i < size; i++) {list.add(i);}System.out.println(list.getClass().getSimpleName() + " 添加耗时:" + (System.currentTimeMillis() - start) + "ms");
}// 测试查询性能
public static void testGet(List<Integer> list) {long start = System.currentTimeMillis();for (int i = 0; i < list.size(); i++) {list.get(i);}System.out.println(list.getClass().getSimpleName() + " 查询耗时:" + (System.currentTimeMillis() - start) + "ms");
}

(二)测试结果(100 万条数据)

集合类型

添加耗时(ms)

随机查询耗时(ms)

中间删除耗时(ms)

ArrayList

35

8

1200

LinkedList

42

58000

15

CopyOnWriteArrayList

1200

7

1100

Collections.synchronizedList(ArrayList)

52

10

1250

(三)结论​

  1. ArrayList:查询无敌,末尾添加高效,但中间删除耗时(需移动大量元素)。​
  2. LinkedList:中间删除高效,但查询极差(遍历链表)。​
  3. CopyOnWriteArrayList:读快写慢,适合读多写少场景。​
  4. synchronizedList:性能略低于 ArrayList,适合轻量并发。

总结:根据场景选择合适的集合​

集合框架的设计遵循 “没有银弹” 原则,不同实现各有侧重:​

  • 频繁查询、末尾添加 → ArrayList。​
  • 频繁中间增删 → LinkedList(元素量小时)或 LinkedList 结合索引定位优化。​
  • 高并发读多写少 → CopyOnWriteArrayList。​
  • 哈希表需求 → HashMap(非线程安全)或 ConcurrentHashMap(线程安全)。​

理解底层原理,才能在性能与安全之间找到平衡,写出更高效、更健壮的代码。

http://www.dtcms.com/a/530934.html

相关文章:

  • 用html做音乐网站深圳响应式网站建设哪家好
  • 做百度移动网站点击一个做外汇的网站叫熊猫什么的
  • wap网站要花多少钱wordpress海报插件
  • 专业的网站建设方案网站建设对企业的帮助
  • 3. 是网站建设的重点自己做的网站主页被人篡改
  • 什么大型网站用python做的线上商城介绍
  • 晋江网站有什么职业做网站发布后打不开
  • 网站建设一百互联贵州网站定制
  • 济南中建设计院 官方网站平台怎么推广
  • 广州市车管所网站建设购物网站的图片轮播怎么做
  • pHP可以做论坛网站吗重庆新闻论坛
  • 营口网站建设wordpress不能登录界面
  • asp与sql做网站别人做的网站不能用
  • php网站开发概念和简介免费行情软件app网站mnu
  • 合肥建网站怀宁做网站
  • 南京做网站公司哪家好煎蛋wordpress
  • 手机营销网站wordpress 命令插件
  • 北京市建设监理协会网站移动应用开发和软件技术的区别
  • 做旅游网站一年能挣多少新品发布会活动方案
  • 网站单页支付宝支付怎么做的网站建设 400电话 广告语
  • 通过输入域名访问自己做的网站怎么样自己建立一个网站
  • 海外网站购物平台有哪些做网站怎么学
  • 惠城网站设计秦皇岛网站群发关键词
  • 企业网站建设管理及推广2345网址导航应用
  • 网站顶一下代码wordpress内容页自定义字段
  • 信通网站开发中心上海闵行邮编
  • 佛山建设工程信息网站网站404页面在哪查看
  • 科技设计网站整合营销是什么
  • 深圳网站制作电话wordpress博客占用cpu
  • 网站后台怎么上传文章企业网站建设遵循的原则