Java基础(二十一)集合(3)List集合
一、List接口
List集合为列表类型,列表的主要特征是以线性方式存储对象。
1.实例化List集合
List接口的常用实现类有ArrayList和LinkedList,根据实际需要可以使用两种方式进行List集合实例化
List<String> list_1 = new ArrayList<>(); List<String> list_2 = new LinkedList<>();
由于List集合可以通过索引位置访问对象,因此,遍历List集合的方法有两种:
Iterator<String> it = list.iterator(); while (it.hasNext()) { String string = (String) it.next(); System.out.println(string); } for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
2.List接口除了拥有Collection接口提供的所有方法,还拥有一些适合于自身的常用方法。
可以看出,List接口提供的适合于自身的常用方法均与索引有关,这是因为List集合为列表类型,以线性方式存储对象,可以通过对象的索引操作对象。
3.常用方法
(1)add(int index, Object obj)向指定索引位置添加对象,set(int index, Object obj)是替换指定索引位置的对象。
package list.jun.iplab; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class MethodTest_addAndset { public static void main(String[] args) { String a = "A", b = "B", c = "C", d = "D", e = "E"; List<String> list = new LinkedList<>(); list.add(a); list.add(e); list.add(d); list.set(1, b); // 将e换成b list.add(2, c); // 在索引值为2的位置插入c,也就是d的前面 Iterator<String> it = list.iterator(); while (it.hasNext()) { String string = (String) it.next(); System.out.println(string); } } } 输出: A B C D
(2)indexOf(Object obj)获得指定对象的最小索引位置,lastIndexOf(Object obj)获得指定对象的最大索引位置。
package list.jun.iplab; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class MethodTest_addAndset { public static void main(String[] args) { String a = "A", b = "B", c = "C", d = "D", e = "E", repeat = "Repeat"; List<String> list = new LinkedList<>(); list.add(a); list.add(repeat); list.add(b); list.add(repeat); list.add(c); list.add(repeat); list.add(d); list.add(repeat); Iterator<String> it = list.iterator(); while (it.hasNext()) { String string = (String) it.next(); System.out.print(string + " "); } System.out.println(); System.out.println(list.indexOf(repeat)); System.out.println(list.lastIndexOf(repeat)); System.out.println(list.indexOf(b)); System.out.println(list.lastIndexOf(b)); } } 输出: A Repeat B Repeat C Repeat D Repeat 1 7 2 2
(3)subList(int fromIndex, int toIndex)用来截取现有List集合中的部分对象,生成新的List集合。
package list.jun.iplab; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class MethodTest_addAndset { public static void main(String[] args) { String a = "A", b = "B", c = "C", d = "D", e = "E", repeat = "Repeat"; List<String> list = new LinkedList<>(); list.add(a); list.add(repeat); list.add(b); list.add(repeat); list.add(c); list.add(repeat); list.add(d); list.add(repeat); Iterator<String> it = list.iterator(); while (it.hasNext()) { String string = (String) it.next(); System.out.print(string + " "); } System.out.println(); list = list.subList(1, 3); Iterator<String> it_1 = list.iterator(); while (it_1.hasNext()) { String string = (String) it_1.next(); System.out.print(string + " "); } } } 输出: A Repeat B Repeat C Repeat D Repeat Repeat B
二、ArrayList类
ArrayList类实现了List接口,由ArrayList类实现的List集合采用数组结构保存对象。
数组结构的优点是便于对集合进行快速的随机访问,如果经常需要根据索引位置访问集合中的对象,使用由ArrayList类实现的List集合的效率较好。
数组结构的缺点是向指定索引位置插入对象和删除指定索引位置对象的速度较慢。
package list.jun.iplab; import java.util.ArrayList; import java.util.List; public class ArrayListTest { public static void main(String[] args) { String a = "A", b = "B", c = "C", d = "D", e = "E"; List<String> list = new ArrayList<>(); list.add(a); list.add(b); list.add(c); list.add(d); list.add(e); System.out.println(list.get((int) (Math.random()*5))); } }
三、LinkedList类
LinkedList(链式队列)类实现了List接口,同时还实现了Queue接口,由Linkedlist类实现的List集合采用链表结构保存对象。
链表结构的优点是便于向集合中插入和删除对象,如果经常需要向集合中插入对象,或者从集合中删除对象,使用由LinkedList类实现的List集合的效率较高。
链表结构的缺点是随机访问对象的速度较慢,如果经常需要随机访问集合中的对象,使用由LinkedList类实现的List集合的效率则较低。
1.常用方法
LinkedList类还根据采用链表结构保存对象的特点,提供了几个专有的操作集合的方法。
2.基本使用
在使用LinkedList类特有的操作集合的方法时,要在创建集合对象时声明对象的类型为LinkedList类型
LinkedList<String> list = new LinkedList<>();
基本使用:
public static void main(String[] args) { String a = "A", b = "B", c = "C", d = "D", e = "E"; String f = "F", g = "G"; LinkedList<String> list = new LinkedList<>(); list.add(a); list.add(b); list.add(c); list.add(d); list.add(e); Iterator<String> it = list.iterator(); // 打印 A B C D E while (it.hasNext()) { String string = (String) it.next(); System.out.print(string + " "); } System.out.println(); System.out.println(list.getFirst()); // 打印A list.addFirst(e); System.out.println(list.getFirst()); // 打印E list.removeFirst(); System.out.println(list.getFirst()); // 打印F
3.使用迭代器删除LinkedList集合中间的元素
例如:链式队列中原有元素A B C D E F,使用迭代器删除第2个元素的操作是:
Iterator<String> it_2 = list.iterator(); String first = it_2.next(); System.out.println(first); // 打印:A String second = it_2.next(); System.out.println(second); // 打印:B it_2.remove(); Iterator<String> it_3 = list.iterator(); while (it_3.hasNext()) { // 打印:A C D E F String string = (String) it_3.next(); System.out.print(string + " "); }
4.在链表队列的中间位置添加元素
链表队列是一个有序集合,每个对象的位置十分重要。LinkedList类中的add方法(包括addFirst和AddLast)将对象添加到链表的尾部。但是,常常需要将元素添加到链表的中间。
由于迭代器是描述集合中位置的,因此这种依赖于位置的add方法将由迭代器负责。
只有对自然有序的集合使用迭代器的add方法添加元素才有实际意义,而无需的集合(例如:Set)就没有add方法。
例如,执行add方法后,将新添加的元素添加到链表的尾部。
list.add(f); Iterator<String> it_1 = list.iterator(); while (it_1.hasNext()) { // 打印结果:A B C D E F String string = (String) it_1.next(); System.out.print(string + " "); }
回顾一下集合框架中的接口:四大类接口Collection、Map、Iterator和RandomAccess。
其中,ListIterator接口是Iterator接口的子接口,其中也包含add方法。
使用LinkedList类的listIterator方法返回一个实现了ListIterator接口的迭代器对象:
ListIterator<String> lIt = list.listIterator();
使用ListIterator的add方法在迭代器位置之前添加一个新对象:原有元素为(A C D E F)
ListIterator<String> lIt = list.listIterator(); lIt.next(); // 越过第一个元素 lIt.add(g); // 在第二个元素之前插入g Iterator<String> it_4 = list.iterator(); while (it_4.hasNext()) { // 打印:A G C D E F String string = (String) it_4.next(); System.out.print(string + " "); }