ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如果像 AI 一样使用 List

如果像 AI 一样使用 List 如果像 AI 一样使用 List一句话总结:List 是 Java 的百宝袋。AI 的用法是——创建用new ArrayList()或collect(toList()),判空用CollectionUtils.isEmpty,批量删用removeIf,批量改用replaceAll,遍历用forEach;并躲开Arrays.asList和subList两个经典坑。相关文档:《如果像AI一样使用工具类-通俗版.md》——CollectionUtils.isEmpty的出处;《如果像AI一样使用Comparator-通俗版.md》——list.sort详见该篇。0. 比喻:百宝袋写法比喻普通人的写法自己缝袋子、手动翻袋子函数式写法用现成袋子,指挥助手干活AI lambda 简写袋子自带说明书,指令指到现成方法1. 创建列表:四种姿势① 普通人的写法:new 逐个 addListStringlistnewArrayList();list.add(A);list.add(B);list.add(C);② 函数式写法:Arrays.asList 快捷创建ListStringlistArrays.asList(A,B,C);③ AI lambda 简写:流式收摊 / 特殊集合// 过滤完直接落成 List(第 3、4 篇的标准三段式)ListStringlistnames.stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());// 空集合 / 单元素:复用不可变实例,零开销ListStringemptyCollections.emptyList();ListStringoneCollections.singletonList(A);2. 判空:isEmpty 与 CollectionUtils.isEmpty① 普通人的写法:null 判断 size 判断if(listnull||list.size()0){return;// 没数据不处理}② 函数式写法:CollectionUtils.isEmpty 一次判完if(CollectionUtils.isEmpty(list)){return;}③ AI lambda 简写:配合提前返回一行守卫if(CollectionUtils.isEmpty(list))return;CollectionUtils.isEmpty(commons-collections4)对null 也返回 true,比list.isEmpty()更安全;list.isEmpty()只适合确定非 null的场合。3. 拷贝:new ArrayList(source)① 普通人的写法:for 逐个复制ListStringcopynewArrayList();for(Stringitem:source){copy.add(item);}② 函数式写法:构造器一步拷贝ListStringcopynewArrayList(source);③ AI lambda 简写:流式拷贝(顺便加工)ListStringcopysource.stream().map(String::trim).collect(Collectors.toList());浅拷贝注意:元素对象本身不会被复制,改元素内部字段两边都会变;只是袋子换了,东西还是那些东西。4. 批量删除:removeIf / removeAll / retainAll① 普通人的写法:迭代器边遍历边删IteratorStringitlist.iterator();while(it.hasNext()){if(EXCLUDE_NAMES.contains(it.next())){it.remove();}}② 函数式写法:removeIf lambdalist.removeIf(item-EXCLUDE_NAMES.contains(item));③ AI lambda 简写:方法引用,并活用两个兄弟方法list.removeIf(EXCLUDE_NAMES::contains);// 删掉名单里的list.removeAll(excludeSet);// 删掉另一个集合里的list.retainAll(allowSet);// 只留另一个集合里的(交集)三兄弟语义:removeIf按规则删,removeAll按集合删,retainAll反向——按集合留。5. 批量修改:replaceAll① 普通人的写法:for set 逐个替换for(inti0;ilist.size();i){list.set(i,list.get(i).trim());}② 函数式写法:replaceAll lambdalist.replaceAll(item-item.trim());③ AI lambda 简写:方法引用list.replaceAll(String::trim);replaceAll是 JDK 8 的批量 set,接收UnaryOperator(第 1 篇的盒子),原地修改每个元素,String::trim一行收工。6. 遍历:forEach 与三种姿势对比① 普通人的写法:增强 forfor(Stringname:list){handle(name);}② 函数式写法:forEach lambdalist.forEach(name-handle(name));③ AI lambda 简写:方法引用list.forEach(this::handle);注意区别:for里可以break/continue,还可以顺手删元素(用迭代器);forEach是每个都处理到底,要提前终止就得回到流式anyMatch/findFirst(第 2 篇)。7. 数组与 List 互转// List → 数组(传 new String[0] 是 AI 的标准姿势,JDK 会自己扩容)String[]arrlist.toArray(newString[0]);// 数组 → List:遍历用 Arrays.stream,取列表用 asList(注意陷阱见第 9 节)list.stream()// 数组转流Arrays.stream(arr).collect(Collectors.toList())// 数组转可变 ListArrays.asList(arr)// 数组转定长视图,不可增删8. 排序:交叉引用// 原地排(第 8 篇 Comparator 专题)list.sort(Comparator.comparing(Person::getAge).reversed());// 新列表排ListPersonsortedlist.stream().sorted(Comparator.comparing(Person::getAge)).collect(Collectors.toList());9. 陷阱:List 的四个经典坑坑 1:Arrays.asList 是定长视图ListStringfixedArrays.asList(A,B);fixed.add(C);// ❌ UnsupportedOperationExceptionfixed.set(0,X);// ✅ 能改值fixed.removeIf(A::equals);// ❌ 同样炸需要可变列表:先包一层new ArrayList(Arrays.asList(...)),或者直接流式collect(toList())。坑 2:subList 是视图,不是拷贝ListStringviewlist.subList(0,2);view.clear();// 原 list 的前两个元素也被清了!list.add(D);// ❌ 结构性修改后,view 再操作就抛 ConcurrentModificationException要截一段独立列表必须拷贝:new ArrayList(list.subList(0, 2))。坑 3:indexOf / contains 是大循环list.indexOf(x)、list.contains(x)都是线性遍历。高频查在不在应该用Set:new HashSet(list)之后set.contains(x)是 O(1)。坑 4:增强 for 里删除会炸for(Stringitem:list){list.remove(item);// ❌ ConcurrentModificationException}删除一律removeIf(第 3 篇详解)。一页速记创建:new ArrayList()常规,collect(toList())流式,emptyList()/singletonList特殊判空:CollectionUtils.isEmpty(list)null 也安全;list.isEmpty()需保证非 null拷贝:new ArrayList(source);subList只是视图,要独立先拷贝批量删:removeIf(规则)/removeAll(集合)/retainAll(留集合)批量改:replaceAll(String::trim)一行原地替换遍历:forEach(this::handle),要 break 就回流的anyMatch/findFirst互转:toArray(new String[0]);Arrays.asList是定长视图,增删会炸高频查值先转Set,别在 List 上反复contains
返回列表