通过前面的学习,我们了解到了List接口中的特有方法,List集合的特点:有序性(存取顺序一致)以及允许元素重复。本节,将会学习List接口中的三大实现类:ArrayList,Vector以及LinkedList。
ArrayList是最常用的List实现类,内部是通过数组来实现,它允许对元素进行快速访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就需要将已有数组的数据复制到新的存储空间中。简而说之,ArrayList适合随机查找与遍历,不适合增加和删除元素
import java.util.ArrayList;
import java.util.Comparator;
public class MyTest {
public static void main(String[] args) {
//List集合:允许元素重复,元素有序(存取顺序一致)
//ArrayList底层数据结构为数组,线程不安全,查询快,增删慢。
ArrayList list = new ArrayList();
list.add(300);
list.add(100);
list.add(500);
list.add(50);
list.add(600);
//遍历集合
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// void sort(Comparator super E> c) 分类列表使用提供的 Comparator比较元素。
list.sort(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//向下转型
Integer a= (Integer) o1;
Integer b= (Integer) o2;
return a-b;
}
});
System.out.println("ArrayList类经过sort()方法进行排序后结果:"+list);
}
}
JDK1.8新增的一个方法也能遍历集合:void forEach(Consumer super E> action)
:执行特定动作的每一个元素的 Iterable直到所有元素都被处理或操作抛出异常。
ArrayList存储字符串并遍历:
import java.util.ArrayList;
import java.util.function.Consumer;
public class MyTest2 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("小明");
list.add("小黄");
//Jdk新增方法forEach()方法可以进行遍历ArrayList集合
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});
}
}
ArrayList存储自定义对象并遍历:
public class Student {
private String name;
private int age;
public Student() {
}
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 +
'}';
}
}
public class MyTest3 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new Student("张三",23));
list.add(new Student("李四",24));
list.add(new Student("王五",25));
list.add(new Student("小明",26));
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
Student stu= (Student) o;
String name = stu.getName();
int age = stu.getAge();
System.out.println(stu.getName()+"===="+stu.getAge());
}
});
}
}
import java.util.ArrayList;
import java.util.function.Consumer;
public class MyTest3 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new Student("张三",23));
list.add(new Student("李四",24));
list.add(new Student("王五",25));
list.add(new Student("小明",26));
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
Student stu= (Student) o;
String name = stu.getName();
int age = stu.getAge();
System.out.println(stu.getName()+"===="+stu.getAge());
}
});
System.out.println("====================");
for (int i = 0; i < list.size(); i++) {
Student stu= (Student) list.get(i);
int age = stu.getAge();
String name = stu.getName();
if (name.equals("张三")) {
list.add(new Student("小黄",25));
}
}
System.out.println(list);
}
}
import java.util.ArrayList;
public class ArrayList去除字符串的重复值 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
list.add("张三");
list.add("小明");
list.add("李四");
list.add("王五");
//思路为创建一个新的Arraylist集合
ArrayList newlist = new ArrayList();
//遍历原先的集合获得每个元素,如果新集合中不含有这个元素,就添加
for (int i = 0; i < list.size(); i++) {
Object o = list.get(i);
if(!newlist.contains(o)){
newlist.add(o);
}
}
System.out.println(newlist);
}
}
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
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 +
'}';
}
//需要重写equals()方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
}
import java.util.ArrayList;
public class ArrayList去除自定义对象元素的重复值 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new Student("张三",23));
list.add(new Student("李四",24));
list.add(new Student("王五",25));
list.add(new Student("张三",23));
ArrayList newlist = new ArrayList();
for (int i = 0; i < list.size(); i++) {
Student stu = (Student) list.get(i);
/*自定义对象需要重写equals()方法,因为contains()方法中比较用到equals()方法,
不重写equals()方法默认比较的是自定义对象的地址值
*/
if(!newlist.contains(stu)){
newlist.add(stu);
}
}
System.out.println(newlist);
}
}
Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性。即线程是安全的,效率低。
Vector类的特有方法 |
---|
void addElement(E obj):增加元素。 |
E elementAt(int index):返回指定索引处的元素。 |
E firstElement() :返回第一个元素。 |
E lastElement() :返回此向量的最后一个元素。 |
void insertElementAt(E obj, int index): 将指定对象作为此向量中的组件插入到指定的 index 处。 |
import java.util.Vector;
public class MyTest {
public static void main(String[] args) {
//Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低。
Vector vector = new Vector();
//void addElement(E obj):增加元素。
vector.add(100);
vector.addElement(200);
vector.addElement(50);
Object o = vector.get(0);
System.out.println(o);
//E elementAt(int index):返回指定索引处的元素。
Object o1 = vector.elementAt(1);
System.out.println(o1);
}
}
import java.util.Vector;
public class MyTest2 {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add(200);
vector.add(500);
vector.add(600);
vector.add(400);
vector.add(100);
vector.add(300);
//E firstElement() :返回第一个元素。
Object o = vector.firstElement();
System.out.println(o);
//E lastElement() :返回此向量的最后一个元素。
Object o1 = vector.lastElement();
System.out.println(o1);
//void insertElementAt(E obj, int index) 将指定对象作为此向量中的组件插入到指定的 index 处。
vector.insertElementAt(50,3);
System.out.println(vector);
}
}
Vector集合中有自己的迭代器,也可以通过迭代器对集合进行遍历。 public Enumeration elements():Vector中获取迭代器。
import java.util.Vector;
public class MyTest3 {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add(200);
vector.add(300);
vector.add(500);
vector.add(600);
vector.add(100);
vector.add(400);
//Vector中获取迭代器
Enumeration elements = vector.elements();
while (elements.hasMoreElements()) {
elements.nextElement();
}
System.out.println(vector);
}
}
ArrayList与Vector的区别与联系 |
---|
1.首先它们的底层物理结构是数组,称为动态数组 |
2.ArrayList线程不安全,效率高;Vector线程安全,效率低 |
3.数组的初始化容量: 如果在构建ArrayList与Vector的集合对象时,没有显示指定初始化容量,Vector的初始化容量为10;ArrayList在Jdk1.6时容量为10,而之后的版本初始化为默认的空数组,如果ArrayList一开始初始化为默认的空数组,那么添加第一个元素时,扩大为默认大小为10的数组。 |
LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
LinkedList的特有方法 |
---|
void addFirst(E e): 在此列表的开始处插入指定的元素。 |
void addLast(E e): 在此列表的最后插入指定的元素。 |
E poll():检索并删除此列表的头(第一个元素)。 |
E pop() :从这个列表所表示的堆栈中弹出一个元素。 |
import java.util.LinkedList;
public class MyTest {
public static void main(String[] args) {
//LinkedList底层数据结构是链表,查询慢,增删快,线程不安全,效率高
LinkedList linkedList = new LinkedList();
linkedList.add(100);
//void addFirst(E e): 在此列表的开始处插入指定的元素。
linkedList.addFirst(200);
//void addLast(E e): 在此列表的最后插入指定的元素。
linkedList.addLast(50);
System.out.println(linkedList);
//E poll():检索并删除此列表的头(第一个元素)。
Object poll = linkedList.poll();
System.out.println(poll);
System.out.println(linkedList);
Object poll1 = linkedList.poll();
System.out.println(poll1);
System.out.println(linkedList);
Object poll2 = linkedList.poll();
System.out.println(poll2);
System.out.println(linkedList);
}
}
import java.util.LinkedList;
public class MyTest2 {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add(100);
linkedList.addFirst(50);
linkedList.addLast(150);
//E pop():从这个列表所表示的堆栈中弹出一个元素。
Object pop = linkedList.pop();
System.out.println(pop);
Object pop1 = linkedList.pop();
System.out.println(pop1);
Object pop2 = linkedList.pop();
System.out.println(pop2);
}
}
import java.util.LinkedList;
public class MyList {
private final LinkedList linkedList;
//构造方法
public MyList(){
//把局部变量转换为成员变量,快捷键为ctrl+alt+f
linkedList = new LinkedList();
}
public void addobj(Object obj){
//添加元素时,后面的元素放在前面元素的前面
linkedList.addFirst(obj);
}
public Object getobj() {
//弹栈,首先会弹出最后放置的元素
Object pop = linkedList.pop();
//弹出后,放在已有元素的最后面
linkedList.addLast(pop);
return pop;
}
}
//测试类
public class MyTest {
public static void main(String[] args) {
MyList myList = new MyList();
myList.addobj(100);
myList.addobj(200);
myList.addobj(300);
myList.addobj(400);
Object getobj = myList.getobj();
System.out.println(getobj);
Object getobj1 = myList.getobj();
System.out.println(getobj1);
Object getobj2 = myList.getobj();
System.out.println(getobj2);
Object getobj3 = myList.getobj();
System.out.println(getobj3);
}
}
本节主要介绍了List接口的三个具体实现类:ArrayList,Vector以及LinkedList。学习三个类中的重要方法。后续我们将学习Set集合,List集合与后面Set集合可以进行比对学习,了解其中的差异。