Java常用集合类
集合类框架图
Collection接口和常用方法
ArrayList常用方法
- add:添加单个元素
- remove:删除指定元素
- contains:查找元素是否存在
- size:获取元素个数
- isEmpty:判断是否为空
- clear:清空
- addAll:添加多个元素
- removeAll:删除多个元素
- containsAll:查找多个元素是否存在
例子
import java.util.ArrayList;
import java.util.List;
public class collection_method {
@SuppressWarnings({ "all" })
public static void main(String[] args) {
List list = new ArrayList();
// 添加元素
list.add(true);
list.add(false);
list.add("jack");
list.add(10);
System.out.println("list=" + list);
// 删除元素
list.remove(0);// 索引删除,删除下标元素
list.remove("jack");// 删除指定元素
System.out.println("list=" + list);
// 获取列表元素个数
System.out.println(list.size());
// 判断列表是否为空
System.out.println(list.isEmpty());
// 清空列表
list.clear();
System.out.println("list=" + list);
// 添加多个元素
List list2 = new ArrayList();
list2.add("三国演义");
list2.add("红楼梦");
list2.add("水浒传");
list2.add("西游记");
list.addAll(list2);// 加入list2的所有元素
System.out.println("list=" + list);
// 查找多个元素是否都存在
System.out.println(list.containsAll(list2));
// 删除多个元素
list.add("数学");
list.removeAll(list2);
System.out.println("list=" + list);
}
}
// 运行结果
list=[true, false, jack, 10]
list=[false, 10]
2
false
list=[]
list=[三国演义, 红楼梦, 水浒传, 西游记]
true
list=[数学]
Collection接口遍历元素
(1)方式1-使用Iterator(迭代器)
- Iterator对象称为迭代器主要用于遍历Collection集合中的元素。
- 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器。
- Iterator仅用于遍历集合,Iterator本身并不存放对象。
执行原理:
-
Iterator iterator = coll.iterator(); //得到一个集合的迭代器。
-
hasNext()判断是否还有下一个元素
-
while(iterator.hasNext()){
? // next() 作用 : 1)指针下移 2)将下移后集合位置上的元素返回
? System.out.println(iterator.next());
-
当退出while循环后,这时iterator迭代器指向的是最后的元素
注意
? 在调用next()方法之前必须要调用hasNext()进行检测。如果下一条记录无效,直接调用next()方法会抛出NoSuchElementException异常。
例子
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class collection_iterator {
@SuppressWarnings({ "all" }) // 禁用所有报错
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 10.1));
col.add(new Book("小李飞刀", "古龙", 5.1));
col.add(new Book("红楼梦", "曹雪芹", 34.6));
System.out.println("col = " + col);
// 遍历col集合
// 1.先得到col对应的迭代器
Iterator iterator = col.iterator();
// 2.使用while循环遍历
while (iterator.hasNext()) {// 判断是否还有数据
// 返回下一个元素,类型是Object
Object obj = iterator.next();
System.out.println("obj = " + obj);
}
}
}
class Book {
private String name;
private String author;
private double price;
// 构造器
public Book(String name, String author, double price) {
super();
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book {name=" + name + ", author=" + author + ", price=" + price + "}";
}
}
//运行结果
col = [Book {name=三国演义, author=罗贯中, price=10.1}, Book {name=小李飞刀, author=古龙, price=5.1}, Book {name=红楼梦, author=曹雪芹, price=34.6}]
obj = Book {name=三国演义, author=罗贯中, price=10.1}
obj = Book {name=小李飞刀, author=古龙, price=5.1}
obj = Book {name=红楼梦, author=曹雪芹, price=34.6}
(2)方式2-使用增强for循环
? 增强for循环,可以代替iterator迭代器。
? 特点:增强for就是简化版的iterator,本质一样。只能用于遍历集合或数组。
基本语法
for(元素类型 元素名:集合名或数组名){
? 访问元素
}
例子
import java.util.ArrayList;
import java.util.Collection;
public class collection_for {
@SuppressWarnings({ "all" })
public static void main(String[] args) {
Collection col = new ArrayList();
col.add(new Book("三国演义", "罗贯中", 10.1));
col.add(new Book("小李飞刀", "古龙", 5.1));
col.add(new Book("红楼梦", "曹雪芹", 34.6));
// 使用增强for
for (Object book : col) {
System.out.println("book = " + book);
}
}
}
class Book {
private String name;
private String author;
private double price;
// 构造器
public Book(String name, String author, double price) {
super();
this.name = name;
this.author = author;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Book {name=" + name + ", author=" + author + ", price=" + price + "}";
}
}
// 运行结果
book = Book {name=三国演义, author=罗贯中, price=10.1}
book = Book {name=小李飞刀, author=古龙, price=5.1}
book = Book {name=红楼梦, author=曹雪芹, price=34.6}
1.List接口
(1)基本介绍
? 1)List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复
? 2)List集合中的每个元素都有其对应的顺序索引,即支持索引。索引是从0开始的
? 3)List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器听元素
(2)常用方法
- void add(int index, Object ele): 在index位置插入ele元素
- boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
- Object get(int index):获取指定index位置元素
- int indexOf(Object obj):返回obj在集合中首次出现的位置
- int lastIndexOf(Object obj):返回obj未次出现的位置
- Object remove(int index):移除指定index位置的元素,并返回此元素Object set(int index, Object ele):设置指定index位置的元素为ele,相当于替换
- List SubList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
例子
import java.util.ArrayList;
import java.util.List;
public class List_01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三丰");
list.add("贾宝玉");
System.out.println("list = " + list);
// void add(int index, Object ele): 在index位置插入ele元素
list.add(1, "玛卡巴卡"); //在张和贾的中间加入元素
System.out.println("list = " + list);
// boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
List list2 = new ArrayList();
list2.add("Tom");
list2.add("Jack");
list.addAll(1, list2); //在第2个元素位置开始添加list2所有元素
System.out.println("list = " + list);
// Object get(int index):获取指定index位置元素
// int indexOf(Object obj):返回obj在集合中首次出现的位置
System.out.println(list.indexOf("Tom"));
// int lastIndexOf(Object obj):返回obj未次出现的位置
list.add("Tom");
System.out.println("list = " + list);
System.out.println(list.lastIndexOf("Tom"));
// Object remove(int index):移除指定index位置的元素,并返回此元素
list.remove(0);
System.out.println("list = " + list);
// Object set(int index, Object ele):设置指定index位置的元素为ele,相当于替换
list.set(4, "Musk");
System.out.println("list = " + list);
//List SubList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
List list3 = list.subList(1, 3);//前闭后开
System.out.println(list3);
}
}
// 运行结果
list = [张三丰, 贾宝玉]
list = [张三丰, 玛卡巴卡, 贾宝玉]
list = [张三丰, Tom, Jack, 玛卡巴卡, 贾宝玉]
1
list = [张三丰, Tom, Jack, 玛卡巴卡, 贾宝玉, Tom]
5
list = [Tom, Jack, 玛卡巴卡, 贾宝玉, Tom]
list = [Tom, Jack, 玛卡巴卡, 贾宝玉, Musk]
[Jack, 玛卡巴卡]
例子
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class List_02 {
@SuppressWarnings({ "all" })
public static void main(String[] args) {
List list = new ArrayList();
list.add("Jack");
list.add("Tom");
list.add("鱼香肉丝");
list.add("北京烤鸭");
// 三种遍历方式
// 1.iterator
System.out.println("=====迭代器=====");
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object object = (Object) iterator.next();
System.out.println("obj = " + object);
}
// 2.增强for
System.out.println("=====增强for=====");
for (Object object : list) {
System.out.println("obj = " + object);
}
// 3.普通for
System.out.println("=====普通for=====");
for (int i = 0; i < list.size(); i++) {
System.out.println("obj = " + list.get(i));
}
}
}
2.ArrayList的注意事项
(1)注意事项
1)ArrayList可以存放null值, 并且可以存放多个
2)ArrayList的底层是用数组来实现的
3)ArrayList是线程不安全的(执行效率高)。在多线程下,不建议使用。
例
import java.util.ArrayList;
public class arraylist01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
//ArrayList的底层是用数组来实现的
//ArrayList可以存放null值
ArrayList al = new ArrayList();
al.add(null);
al.add("Tom");
al.add(null);
System.out.println("al = " + al);
}
}
(2)ArrayList扩容机制
1)ArrayList中维护了一个Object类型的数组elementData。
2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容为10,如需要再次扩容,则扩容大小为elementData的1.5倍。
3)如果使用指定大小的构造器,则初始容量为指定的大小,再次扩容则为elementData的1.5倍。
3.Vector的注意事项
1)Vector底层也是一个对象数组,protected Object[] elementData;
2)Vector是线程安全的(执行效率不高)。Vector类的操作方法带有synchronized
3)在开发过程中,需要线程同步安全时,考虑使用Vector
4)扩容是默认2倍,可自定义扩容大小。
4.LinkedList的注意事项
(1)LinkedList的全面说明
1)LinkedLIst底层实现了双向链表和双端队列的特点
2)可以添加任意元素,元素可重复、可为null
3)线程不是安全的,没有实现同步
(2)LinkedList的底层操作机制
- LinkedLIist底层维护了一个双向链表
- LinkedList中维护了两个属性first和last,分别指向首节点和尾节点。
- 每个节点里面维护了prev,next,item三个属性,prev:指向前一个,通过next指向后一个节点,最终实现双向链表。
- LinkedList中元素的添加或删除,不是通过数组实现的,效率相对较高。
例子
import java.util.LinkedList;
public class LinkedList_01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
LinkedList ll = new LinkedList();
ll.add(1);
ll.add(2);
ll.add(3);
System.out.println("linkedList = " + ll);
// 删除一个节点
ll.remove();//删除第一个节点
System.out.println("linkedList = " + ll);
//修改某个节点
ll.set(1, 99);
System.out.println("linkedList = " + ll);
// 得到某个结点对象
System.out.println(ll.get(1));
// 遍历
// 因为LinkedList是实现了List接口,所以遍历方式一样
// 例:增强for
for (Object obj : ll) {
System.out.println("LinkedList = " + obj);
}
}
}
5.ArrayList和LinkedList比较
底层结构 | 增删的效率 | 改查的效率 | |
---|---|---|---|
ArrayList | 可变数组 | 较低数组扩容 | 较高 |
LinkedList | 双向链表 | 较高,通过链表追加 | 较低 |
如何选择:
1)如果改查的操作较多,选择ArrayList
2)如果增删的操作较多,选择LinkedList
3)一般来说,在程序中大多数都是查询,因此大部分情况下会选择ArrayList
4)不适合用于单线程,LinkedList和ArrayList的线程不是安全的。