使用 set 的 has() 方法实现黑白名单过滤最轻量高效,时间复杂度稳定 o(1),需预先标准化数据并复用 set 实例,支持动态增删但不可用 weakset。

直接用 Set 的 has() 方法判断元素是否存在,是实现黑白名单过滤最轻量、最高效的方式——时间复杂度稳定 O(1),比数组 includes() 或对象属性查找更可靠。
构建黑白名单 Set
把名单数据一次性转为 Set,避免重复创建或遍历。注意字符串大小写、空格等需提前标准化。
- 黑名单示例:
const blacklist = new Set(['admin', 'root', 'test']); - 白名单示例:
const whitelist = new Set(['user_123', 'editor_456']); - 若来源是数组或 JSON 字符串,先清洗再构造:
new Set(rawList.map(s => s.trim().toLowerCase()))
用 has() 快速过滤单个值
对每个待校验值调用 set.has(value),返回布尔值,逻辑清晰且无隐式类型转换风险。
- 黑名单拦截:
if (blacklist.has(username)) { return false; } - 白名单放行:
if (!whitelist.has(userId)) { throw new Error('Access denied'); } - 注意:Set 严格按值匹配,
new Set([1, '1']).has(1)返回 true,但.has('1')也返回 true —— 因为 1 和 '1' 是不同值,不会自动转换类型
配合 filter() 批量处理数组
对用户列表、请求参数等批量数据做筛选时,直接链式调用 filter() + has(),简洁且性能好。
- 过滤出不在黑名单中的用户名:
users.filter(u => !blacklist.has(u.name)) - 只保留白名单内的 ID:
ids.filter(id => whitelist.has(String(id)))(如后端传数字 ID,前端存为字符串,需显式转换) - 避免在循环内重复创建 Set,务必把 Set 实例定义在外部作用域
进阶:动态更新与内存管理
黑白名单可能随配置变更,Set 支持增删,但要注意引用和同步问题。
- 添加新黑名单项:
blacklist.add('guest'); - 移除某项:
blacklist.delete('test'); - 若名单很大且长期不用,可考虑 WeakSet?不适用——WeakSet 只接受对象,且不能遍历,黑白名单通常用字符串/数字,必须用 Set
- 频繁更新时,避免反复
new Set(...),直接复用实例并操作方法
不复杂但容易忽略:Set 构造时去重自动生效,传入重复项不影响性能;has 查找不触发迭代,也没有原型链查找开销,真正做到了“查得快、判得准”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











