Java:List(一)——概述
说明
在集合类中,List是最基础的一种集合——有序List。
List的行为和数组几乎相同:List内部按照放入元素先后顺序存放,每个元素都可以通过索引确定自己的位置,List的索引和数组相同,都是从0开始。
我们使用List而不是数组的原因是,使用数组增删元素时,会非常不方便。
在实际应用中,需要增删元素的有序List,我们使用最多的是ArrayList。
0、增删元素的原理
内部数组如果已满,就生成一个更大的数组,把原数组元素复制到新数组,接着用新数组代替原数组。
ArrayList把添加和删除元素的操作封装起来,让我们操作List类似操作数组,却不用关心内部元素如何移动。
1、主要方法
List<E>接口的几个主要方法:
方法返回值 |
方法 |
说明 |
int | size() | 获取List大小(实际元素个数) |
boolean | add(E e) | 在末尾加一个元素 |
boolean | add(int index , E e) | 在指定索引添加一个元素 |
E | remove(int index) | 删除指定索引处的元素 |
boolean | remove(Object e) | 删除第一次出现的元素o |
E | get(int index) | 获取指定索引的元素 |
2、ArrayList与LinkedList
以上方法就是实现List接口的实际类之一ArrayList的主要方法,这种类型内部实际是数组。
还有一种实现List接口的实际类LinkedList,这种类型内部实现是链表。
两者比较:
通常情况下,总是优先使用ArrayList。
3、List的特点
- List内部元素可以重复;
- List可以添加null。
4、创建List
4.1、List.of( ... ):自己指定List中的元素,参数可以是若干元素或者若干元素构成的Array T[]
除了使用ArrayList与LinkedList,我们还可以通过List的of()方法,根据给定元素快速创建List:
List <Integer> list = List.of(1,2,5);
但是List.of( )不接受null值,如果传入null,会抛出NullPointerException异常。
4.2、List.copyOf( Collection<? extends E> coll ):返回指定Collection中的元素构成的List
5、遍历List
5.1、for循环+get方法;
List <String> list = List.of("apple","pear","banana"); for(int i=0; i<list.size(); i++){ String s = list.get(i); ... }
5.2、迭代器Iterator;
Iterator本身也是一个对象,它由List实例通过Iterator()创建。
使用Iterator,不需要关心List中元素的实际类型,访问效率也是最高的。
Iterator利用两个方法实现遍历:
- boolean hasNext():判断是否有下一个元素;
- E next():返回下一个元素。
List <String> list = List.of("apple","pear","banana"); for ( Iterator <String> it = list.iterator() ; it.hasNext() ; ){ String s = it.next(); ... }
5.3、for each循环(最常用);
Java的for each循环就是利用Iterator遍历的,用起来更方便:
List<String> list = List.of("apple", "pear", "banana"); for (String s : list) { System.out.println(s); }
实际上,只要实现了Iterator接口的集合类都可以直接用for each循环来遍历,Java编译器本身不知道如何遍历集合,它只会把for each变成Iterator调用,原因就在于Iterator接口定义了一个Iterator <E> iterator(),强迫集合类必须返回一个Iterator实例。
6、List与Array转换
①List→Array
1、list.toArray():List→Object[ ]
Object [] array = list.toArray(); for (Object s : array){ System.out.println(s); }
这种方法会丢失类型信息,所以不常用。
2、list.toArray( T[ ] ):List→T[ ]
Integer [] array = list.toArray(new Integer[3]); //或 Integer [] array = new Integer [3]; list.toArray( array ); for( Integer n : array ){ System.out.println(n); }
这里的T与构建List接口时定义的泛型E可以不同。比如,我们可以传入一个Number作为T,返回的仍然是Number类型:
List <Integer> list = List.of(1,2,3); Number [] array = list.toArray(new Number [3]); for (Number n : list){ System.out.println(n); }
但是T和E不能不匹配,比如用String[ ]数组去承接List的Integer元素,就会抛出ArrayStoreException这个异常。
如果我们传入的数组大小和实际的List大小不同,那么会有两种情况:
- 传入小数组,会在List内部创建一个新的大小正好的数组,返回;
- 传入大数组,填充元素后多余元素补null。
最常用
实际使用时,为了确保传入一个大小适当的数组,通常在用list.size构建数组:
Integer [] array = list.toArray( new Integer [ list.size() ] );
3、list.toArray( IntFunction <T[ ]> generator )
还有一种更简洁的写法是通过List接口定义的T [ ] toArray( IntFunction <T[ ]> generator )方法:
Integer [] array = list.toArray(Integer[] :: new)
这种函数式写法我们在之后会讲到。
②Array→List
把Array变为List很简单,可以直接通过List.of( T... ):
Integer [] array = [1,2,3];
List<Integer> list = List.of( array );
对于JDK 11之前的版本,可以用Arrays.asList( T... )把Array转为List。
不过,返回的List不一定是ArrayList或LinkedList,因为List只是一个接口,所有返回的List(包括List.of( ... ))都是Read-Only List,只能访问它的元素,而不能对其增删(add、remove方法),如果调用remove、add会抛出UnsupportedOperationException。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性