List系集合
Part ZERO.
- 集合在任何时候存储的都是引用。它不能直接存储基本数据类型,只能存储引用数据类型。更具体地说,集合存储的是对象的内存地址。
- 集合本身也是一个对象。
- 集合存储的是地址。
- 在Java中,有很多种集合,每种集合的内部数据结构不同。有的可能是二叉树,有的可能是链表,也有的可能是哈希表等等。
- 各种集合类都在java.util.*下。
- 在Java中集合分为两大类,一类以单个方式存储元素,继承Collection接口;另一类以键值对存储元素,继承Map接口。
- List具备有序可重复性,Set是无序不可重复性。
- ArrayList 底层数据结构为数组,且线程不安全;LinkedList底层数据结构为双向链表;Vector底层数据结构为数组,且线程安全,因为效率较低,现在使用较少。
Part ONE. Collection集合概论
Collection
- 主要分为两个分支——List系集合与Set系集合。
1. 常用API
Collection<String> coll = new ArrayList<>();
/*************************
1. 添加与删除元素
*/
coll.add("Apple"); //添加第一个元素
coll.add("Apple"); //添加第二个元素.Collection可以重复
coll.add("Banana"); //添加第三个元素.Collection具有有序性
coll.remove("Apple"); //清除某个元素。通过元素名清除,在Collection中无索引.remove方法清除成功则返回true,反之返回false.
System.out.println(coll); //remove方法只会就近地清除一个与之匹配的元素
coll.clear(); //清空集合中的所有元素
System.out.println(coll);
/*************************
2. 搜索元素
*/
coll.add("Apple");
coll.add("Apple");
coll.add("Banana");
System.out.println(coll.contains("Apple")); //判断Collection中是否有某个元素,返回布尔值
System.out.println(coll.contains("Cherry")); //此时返回false
/*************************
3. 判断Collection中是否有元素
*/
coll.isEmpty(); //判断集合中是否有元素,如果有元素则返回true,反之返回false
int size = coll.size(); //返回集合中的元素个数
/*************************
4. Collection
*/
Object[] array = coll.toArray(); //将coll里的元素深拷贝到Object数组中.
System.out.println(Arrays.toString(array));
Collection<String> collCopy = new ArrayList<>();
collCopy.addAll(coll); //将coll里的元素深拷贝到collCopy中.
System.out.println(collCopy);
2. 遍历
迭代器遍历
Collection<String> coll = new ArrayList<>();
coll.add("Apple");
coll.add("Banana");
coll.add("Cherry");
coll.add("Leechee");
System.out.println(coll);
//1. 迭代对象
Iterator<String> iter = coll.iterator(); //返回当前集合的迭代器对象
String ele1 = iter.next(); //输出coll的第一个元素
String ele2 = iter.next(); //输出coll的第二个元素
String ele3 = iter.next(); //输出coll的第三个元素
String ele4 = iter.next(); //输出coll的第四个元素
String ele5 = iter.next(); //coll没有第五个元素,故会抛出NoSuchElementException异常
//2. 利用迭代器遍历集合
Iterator<String> iter2 = coll.iterator();
while(iter2.hasNext()){
System.out.println(iter2.next());
}
增强for循环遍历
Collection<String> coll = new ArrayList<>();
coll.add("Apple");
coll.add("Banana");
coll.add("Cherry");
coll.add("Leechee");
for (String str: coll){
System.out.println(str);
}
lambda表达式遍历
这种方法本质上是for循环遍历,只不过形式上用lambda表达式简化。
Collection<String> coll = new ArrayList<>();
coll.add("Apple");
coll.add("Banana");
coll.add("Cherry");
coll.add("Leechee");
coll.forEach(str -> System.out.println(str));
Part TWO. List系列集合
List
1. 特点
- 有序:存储和取出的元素一致。
- 索引:因为List集合是有序的,所以可以通过下标索引。
- 可重复:存储的元素可以重复。
2. 常用API
List<String> list = new ArrayList<>();
/*****************
1. 增删元素
*/
list.add("Apple");
list.add(0, "Banana"); //加入索引值,在指定位置插入新元素
list.add("Cherry"); //默认在集合的后面追加元素
System.out.println(list);
list.remove("Apple"); //通过元素值删除元素。返回一个布尔值
list.remove(1); //通过索引删除元素。返回被删除元素的值
System.out.println(list);
list.set(1, "Cherries"); //通过下标索引修改目标元素
/*****************
2. 索引元素
*/
System.out.println(list.get(0)); //通过下标索引元素
3. 遍历
除了List继承自Collection的遍历方法外,它还可以通过索引遍历。
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
for (int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
4. 删除List里的元素
- 由于List系集合里的元素是可以重复的,而List提供的remove方法只能删除一个满足条件的元素,所以当我们需要删除所有List集合中的所有满足条件的元素时,就需要另外设计算法删除了。
- 在这里利用迭代器删除集合中所有满足条件的元素。
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Cherry");
list.add("Leechee");
list.add("Cherry");
System.out.println(list);
//四个步骤
Iterator<String> iter = list.iterator(); //1. 创建
while(iter.hasNext()){ //2. 循环迭代
String str = iter.next(); //3. 移动
if ("Cherry".equals("Cherry")){
iter.remove(); //4. 删除 //注意,这里是调用了Iterator的remove方法
}
}
System.out.println(list);
ArrayList
1. 底层原理
- ArrayList的数据结构是顺序表。在创建一个ArrayList对象时,构造器会构造长度为10的数组。但是虽然创建的对象内部有长度为10的数组,但里面实际存放的元素个数为零,然后我们可以通过add方法添加元素。
- 如果ArrayList集合内部的元素个数即将大于内部数组长度时,ArrayList会重新构造更长的数组。将原有和新增加的元素全部深拷贝到新数组里后,之前的数组会被回收。
- 相比于LinkedList,ArrayList的索引速度会更快。但是增删元素的效率相比较低。
LinkedList
1. 底层原理
- LinkedList的数据结构是链表。在每个LinkedList对象内部,会存储集合头部和尾部的元素地址。
- 相比于ArrayList,LinkedList对头部和尾部的增删操作效率更高,但是索引速度相比更慢。
2. 常用API
LinkedList<String> linked = new LinkedList<>();
linked.addFirst("Banana"); //在链表头部插入元素
linked.addLast("Cherry"); //在链表尾部追加元素,像是压栈
linked.add("Apple"); //在链表尾部追加元素。add与addLast本质上一样
System.out.println(linked);
System.out.println(linked.getFirst()); //获取链表的第一个元素
System.out.println(linked.getLast()); //获取链表的最后一个元素
System.out.println(linked.removeFirst()); //返回链表的第一个元素后,删除链表中的第一个元素。像是弹栈
System.out.println(linked.removeLast()); //返回链表的最后一个元素后,删除链表中的最后一个元素。像是出队列
System.out.println(linked);
The END.
参考资料
Overview (Java SE 17 & JDK 17) (oracle.com)
Java入门基础视频教程,java零基础自学首选黑马程序员Java入门教程(含Java项目和Java真题)_哔哩哔哩_bilibili