Arrays.asList返回的List不可增删,因底层为固定大小的静态ArrayList,调用add/remove抛UnsupportedOperationException;正确做法是new ArrayList(Arrays.asList(...))。

Arrays.asList返回的List不能add/remove
用 Arrays.asList(str.split(",")) 看似一步到位,但这个List是固定大小的——底层是Arrays内部的静态ArrayList,不支持增删操作。一旦调用 add() 或 remove(),立刻抛出 UnsupportedOperationException。
常见错误现象:
代码跑着跑着在某次 list.add("x") 崩了,堆栈里只有 UnsupportedOperationException,没提示“因为是只读视图”。
- 正确做法:包装成可变List,比如
new ArrayList(Arrays.asList(...)) - 如果只是遍历或读取,
Arrays.asList没问题,性能略好(少一次拷贝) - 注意:它对原始数组/分割结果是引用关系,改原字符串不影响,但若split后修改了数组元素(极少发生),会影响该List
split("\s+")和split(" ")行为完全不同
空格分隔最常踩坑:写 str.split(" ") 只按单个空格切,前后/中间多个空格会产生空字符串;而 str.split("\s+") 才真正按“一个或多个空白字符”切,且默认丢弃首尾空串。
使用场景:解析用户输入、CSV片段、日志字段等含不规则空格的文本。
立即学习“Java免费学习笔记(深入)”;
-
"a b c".split(" ")→["a", "", "b", "", "", "c"] -
"a b c".split("\s+")→["a", "b", "c"] - 更稳妥的写法:
str.trim().split("\s+"),避免开头结尾空格导致首尾空元素 - 正则中
\s包含空格、制表符、换行符,比手写"[ ]"更可靠
split limit参数控制分割次数和尾部空串保留
split 的第二个参数 limit 不只是“最多切几段”,它直接影响空字符串是否保留、数组长度是否截断。
性能影响:limit ≠ 0 时,split会在达到次数后停止解析,对超长字符串有轻微优化;但日常用不到,别为这点性能牺牲可读性。
-
"a,,b,".split(",", -1)→["a", "", "b", ""](保留所有空串) -
"a,,b,".split(",", 0)→["a", "", "b"](丢弃末尾空串) -
"a,,b,".split(",", 2)→["a", ",b,"](只切第一刀,剩下全当最后一段) - 日常推荐用
split(",", -1)或split(",", 0),明确意图;避免裸写split(",")(等价于limit=0,容易误判空串行为)
Java 8+推荐用Stream替代Arrays.asList+split
如果目标是转成真正可变、支持函数式操作的List,Stream 写法更直接,也绕过了 Arrays.asList 的限制。
兼容性注意:Java 8+可用;Android需minSdk ≥ 24,旧项目慎用。
- 基础写法:
Arrays.stream(str.split(",")).collect(Collectors.toList()) - 带空字符串过滤:
Arrays.stream(str.split(",")).filter(s -> !s.isEmpty()).collect(Collectors.toList()) - 自动trim每项:
Arrays.stream(str.split(",")).map(String::trim).collect(Collectors.toList()) - 性能上,比
new ArrayList(Arrays.asList(...))多一次遍历,但代码意图清晰,维护成本低
真正麻烦的不是怎么写,而是哪天你发现List突然不能add了,才回头翻文档——那个 Arrays.asList 返回的List,连 instanceof ArrayList 都是false。










