1.首先,来理解一下集合的概念,集合接口又是啥?
集合的基本框架是这样的:
可见集合包括了很多东西,但在这里主要讲List接口的两个常用的实现类:ArrayList(数组列表)和LinkedList(双重链接列表),那他们是啥呢?
他们之间的关系可以用下图表示,这样看起来比较直观,
2.ArrayList和LinkedList的区别:
由于数组列表底层是基于Object数组实现,那么如果在ArrayList的中间插入或删除元素则会使插入位置后面所有的元素在内存中移动所以性能很差,这种情况就要用LinkedList。ArrayList的随机访问性则要优于LinkedList,LinkedList的插入或删除元素则要优于ArrayList。如下图所示:
3. /* List主要方法:
i. add(Object element):向列表的尾部添加指定的元素。
ii. add(int index, Object element) :在列表的指定位置插入指定元素。
iii. get(int index): 返回列表中指定位置的元素。
iv. clear() :从列表中移除所有元素。
v. isEmpty() :如果列表不包含元素,则返回 true。size() ==0
vi. Iterator iterator() :返回按适当顺序在列表的元素上进行迭代的迭代器,可通过迭代器进行循环。
vii. ListIterator<E> listIterator(): 返回此列表元素的列表迭代器(按适当顺序)。
viii. remove(int index) :移除列表中指定位置的元素。
ix. size() :返回列表中的元素数。
x. subList(int fromIndex, int toIndex) :返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的子列表(视图)。
xi. contains(Object o):如果列表包含指定的元素,则返回 true,遵循对象的equals()协定和==。
xii. Object[] toArray(): 返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)
*/
4.以下为ArrayList的演示代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author yyh on 2020/4/1 20:20
*/
public class ArrayListDemo1 {
public static void main(String[] args) {
//list接口
List list = new ArrayList();//多态性
/*引用实例也可以这样List list = new LinkedList();因为LinkedList(双重链表)也实现了List接口*/
//i. add(Object element):向列表的尾部添加指定的元素。
list.add("aaa");//index:0
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add("eee");
list.add("fff");//index:list.size()-1 = 5
//ii. add(int index, Object element) :在列表的指定位置插入指定元素。
list.add(1, "kkk");
System.out.println(list);
// iii.get(int index): 返回列表中指定位置的元素。
System.out.println("得到index --> 1 :"+list.get(1));
//System.out.println("index --> 7 :"+list.get(7));异常、越界,out:java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
//v. isEmpty() :如果列表不包含元素,则返回 true。size() ==0
System.out.println(list.isEmpty()? "列表为空,无元素" : "列表不为空,有元素");
//vi. Iterator iterator() :返回按适当顺序在列表的元素上进行迭代的迭代器,可通过迭代器进行循环。
//vii. ListIterator<E> listIterator(): 返回此列表元素的列表迭代器(按适当顺序)。
//viii. remove(int index) :移除列表中指定位置的元素。
System.out.println("移除index --> 1 :"+list.remove(1));
System.out.println("移除后的列表:"+list);
boolean aaa = list.remove("aaa");
System.out.println("aaa是否被移除:"+aaa);
System.out.println("移除后的列表:"+list);
//ix. size() :返回列表中的元素数。
System.out.println("列表中的元素数:"+list.size());
//x. subList(int fromIndex, int toIndex) :返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的子列表(视图)。
List subList = list.subList(1, 3);
System.out.println(list+"中1~2位置的元素有:"+subList);
//xi. contains(Object o):如果列表包含指定的元素,则返回 true,遵循对象的equals()协定和==。
if (list.contains("fff")) {
System.out.println(list+"中包含fff");
}
//xii. Object[] toArray(): 返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
//iv. clear() :从列表中移除所有元素。
list.clear();
System.out.println("列表清理后元素为:"+list);
System.out.println("列表大小为:"+list.size());
}
}
其输出:
[aaa, kkk, bbb, ccc, ddd, eee, fff]
得到index --> 1 :kkk
列表不为空,有元素
移除index --> 1 :kkk
移除后的列表:[aaa, bbb, ccc, ddd, eee, fff]
aaa是否被移除:true
移除后的列表:[bbb, ccc, ddd, eee, fff]
列表中的元素数:5
[bbb, ccc, ddd, eee, fff]中1~2位置的元素有:[ccc, ddd]
[bbb, ccc, ddd, eee, fff]中包含fff
[bbb, ccc, ddd, eee, fff]
列表清理后元素为:[]
列表大小为:0
Process finished with exit code 0
上面的方法中还有
//vi. Iterator iterator() :返回按适当顺序在列表的元素上进行迭代的迭代器,可通过迭代器进行循环。
//vii. ListIterator listIterator(): 返回此列表元素的列表迭代器(按适当顺序)。 这些方法没展示,以及
//xi. contains(Object o):如果列表包含指定的元素,则返回 true,遵循对象的equals()协定和==。的再次介绍,
接着往下看:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object other){
//参数对象为空,无可比性
if (other == null) {
return false;
}
//创建对象的类型不一样,无可比性
if (this.getClass() != other.getClass()) {
return false;
}
//参数类型的实例与当前实例的类型相同
Student student = (Student) other;
return this.getName().equals(student.getName()) && this.getAge() == student.getAge();
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* @author yyh on 2020/4/1 21:17
*/
public class ArrayListDemo2 {
public static void main(String[] args) {
//list接口
List list = new ArrayList();//多态,引用实例
//i. add(Object element):向列表的尾部添加指定的元素。
list.add("aaa");//index:0
list.add("bbb");
list.add("ccc");
list.add("ddd");
list.add(null);
list.add("eee");
list.add(666);//666:int --> Integer,自动装箱,相当于new Integer(666)
list.add("fff");//index:list.size()-1 = 5
/**
* 列表的3种遍历方式
* 1.fori
* 2.foreach
* 3.Iterator迭代器
*/
//1.fori
System.out.println("---------1.用fori方式输出---------");
for (int i = 0; i < list.size(); i++) {
System.out.printf("index --> "+ i+"的元素是"+list.get(i)+"\n");
}
System.out.println();
//2.foreach
System.out.println("---------2.用foreach方式输出---------");
for (Object o : list) {
System.out.println(o);
}
System.out.println();
//3.Iterator迭代器
//vi.Iterator iterator() :返回按适当顺序在列表的元素上进行迭代的迭代器,可通过迭代器进行循环。
/* 在列表上建立此列表的迭代器,迭代器中拥有一个指针,开始时指针指向第一个元素之前
当调用迭代器的next()方法时,将获取迭代器中当前迭代的元素;调用hasNext()可以检查当前迭代位置的后面是否还有可以迭代的元素*/
System.out.println("---------3.用Iterator迭代器方式输出---------");
Iterator iterator = list.iterator();
for (; iterator.hasNext(); ) {
Object next = iterator.next();
System.out.println(next);
}
/*或用while循环也行,不过此时列表已经指向最后一个元素之后,没有值了,
此时需要iterator = list.iterator();重新让指针指向第一个元素前
iterator = list.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}*/
//vii. ListIterator<E> listIterator(): 返回此列表元素的列表迭代器(按适当顺序)。
System.out.println("----------4.ListIterator迭代器:从前往后输出----------");
ListIterator listIterator = list.listIterator();
while (listIterator.hasNext()) {
System.out.println("index --> "+listIterator.nextIndex()+"的元素是"+listIterator.next());
}
System.out.println("----------ListIterator迭代器:从后往前走输出----------");
while (listIterator.hasPrevious()) {
System.out.println("index --> "+listIterator.previousIndex()+"的元素是"+listIterator.previous());
}
System.out.println("-----------------------------------------------------------------------------------");
//xi. contains(Object o):如果列表包含指定的元素,则返回 true,遵循对象的equals()协定和==。
ArrayList studentList = new ArrayList();
studentList.add(new Student("Q", 11));
studentList.add(new Student("W", 11));
studentList.add(new Student("E", 11));
studentList.add(new Student("R", 11));
studentList.add(new Student("T", 11));
System.out.println(studentList);
Student youyu = new Student("youyu", 21);
if (studentList.contains(youyu)) {
System.out.println("列表中包含"+youyu);
}else
System.out.println("列表中不包含"+youyu);
//viii. remove(int index) :移除列表中指定位置的元素。
if (studentList.remove(youyu)) {
System.out.println("从列表中成功移除"+youyu);
}else
System.out.println("移除"+youyu+"失败");
}
}
输出如下:
---------1.用fori方式输出---------
index --> 0的元素是aaa
index --> 1的元素是bbb
index --> 2的元素是ccc
index --> 3的元素是ddd
index --> 4的元素是null
index --> 5的元素是eee
index --> 6的元素是666
index --> 7的元素是fff
---------2.用foreach方式输出---------
aaa
bbb
ccc
ddd
null
eee
666
fff
---------3.用Iterator迭代器方式输出---------
aaa
bbb
ccc
ddd
null
eee
666
fff
----------4.ListIterator迭代器:从前往后输出----------
index --> 0的元素是aaa
index --> 1的元素是bbb
index --> 2的元素是ccc
index --> 3的元素是ddd
index --> 4的元素是null
index --> 5的元素是eee
index --> 6的元素是666
index --> 7的元素是fff
----------ListIterator迭代器:从后往前走输出----------
index --> 7的元素是fff
index --> 6的元素是666
index --> 5的元素是eee
index --> 4的元素是null
index --> 3的元素是ddd
index --> 2的元素是ccc
index --> 1的元素是bbb
index --> 0的元素是aaa
-----------------------------------------------------------------------------------
[Student{name='Q', age=11}, Student{name='W', age=11}, Student{name='E', age=11}, Student{name='R', age=11}, Student{name='T', age=11}]
列表中不包含Student{name='youyu', age=21}
移除Student{name='youyu', age=21}失败
Process finished with exit code 0
关于equals方法单独拿出来再看一下
package list;
/**
* @author yyh on 2020/4/2 20:21
*/
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object other){
//参数对象为空,无可比性
if (other == null) {
return false;
}
//创建对象的类型不一样,无可比性
if (this.getClass() != other.getClass()) {
return false;
}
//参数类型的实例与当前实例的类型相同
Student student = (Student) other;
return this.getName().equals(student.getName()) && this.getAge() == student.getAge();
}
public static void main(String[] args) {
Student kk = new Student("you",12);
Student jj = new Student("you", 12);
if (kk.equals(jj)) {
System.out.println("kk = jj");//out(输出):kk = jj
}
}
}
5.LinkedList
a) LinkedList内部的每一个元素都有两个指针,一个指向当前元素的上一个元素叫前趋,而另一个指针则指向当前元素的下一个元素叫后继。
b) 如果向LinkedList中加入或删除元素只需改变前趋和后继所指向的元素就可以了。因此在对List做插入或删除操作使用LinkedList性能会更好。这些方法没有在Collection和List接口中声明
/**
* i.LinkedList类额外新加了一些方法(list接口没有的):
* addFirst(), addLast(), removeFirst(), removeLast(),getFirst(),getLast()……..。
* 这些方法在Collection和List接口是没有声明的。
*/
以下为LinkedList的演示代码:
package list;
import java.util.Iterator;
import java.util.LinkedList;
/**
* @author yyh on 2020/4/2 21:30
*/
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add("aaa");
linkedList.add("bbb");
linkedList.addFirst("111");
linkedList.addLast("444");
System.out.println(linkedList);
System.out.println(linkedList.getFirst());
System.out.println(linkedList.getLast());
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("remove First --> "+linkedList.removeFirst());
System.out.println("remove Last --> "+linkedList.removeLast());
System.out.println("show linkedlist :"+linkedList);
}
}
输出:
[111, aaa, bbb, 444]
111
444
111
aaa
bbb
444
remove First --> 111
remove Last --> 444
show linkedlist :[aaa, bbb]
Process finished with exit code 0