
JavaSE中的集合类都实现了Iterator接口,这个接口用于集合对象的遍历,在接下来的集合工具类详解中会讲解如何遍历集合。
同样,各个集合类也都实现了Collection接口,其中定义了一些集合通用的方法,例如集合大小、遍历器、流、是否包含、移除元素、是否为空等等:

集合实现类主要可以分为四部分,即List(列表)、Set(集合)、Queue(队列)、Map(映射)。这些集合实现类除了Map外都实现了Collection接口。
List(列表)、Set(集合)、Queue(队列)、Map(映射)的常用实现类如下图所示:

import java.util.ArrayList;
import java.util.Arrays;
public class DifferenceBetweenArrayAndCollection {
public static void main(String[] args) {
//长度区别:
//数组固定长度
try {
String[] strings=new String[3];
for (int i = 0; i < 10; i++) {
strings[i]="String"+i;
}
} catch (Exception e) {
System.out.println("数组固定长度,不可以超过预定义长度");
}
//集合通过封装表现出来长度可自适应,除非内存爆满,才会存不下
try {
ArrayList stringArrayList=new ArrayList<>();
int amount=100;
for(int i=0;i doubleArrayList=new ArrayList<>();
doubleArrayList.add(0.1);
doubleArrayList.add(0.2);
doubleArrayList.add(0.3);
System.out.println("集合存储基本数据类型需要用包装类:"+ doubleArrayList);
// 类型数量:
// 一个数组只能存定义好的一种类型的数据
try {
//chars[0]="aaaa";
throw new Exception();
} catch (Exception e) {
System.out.println("数组只能存定义好的类型数据");
}
// 一个集合可以存储不同类型的数据。
ArrayList list=new ArrayList<>();
list.add("string");
list.add(1);
list.add(0.1);
list.add('c');
list.add(new ArrayList<>());
System.out.println("集合可以存不同类型的数据,但是一般情况用于存同类型数据:"+list);
}
}
List中常用实现类有ArrayList、LinkedList、Vector、Stack,它们的数据结构都是线性表,其中ArrayList、Vector、Stack底层是数组(顺序表),LinkedList底层是链表。
底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList integerArrayList=new ArrayList<>();
//添加元素
for (int i = 0; i < 20; i++) {
integerArrayList.add(i);
}
System.out.println("添加元素:"+integerArrayList);
integerArrayList.add(2,10);
System.out.println("指定位置插入元素"+integerArrayList);
//删除元素
integerArrayList.remove(1);
System.out.println("按索引1删除元素"+integerArrayList);
integerArrayList.remove(15);
System.out.println("按索引删除元素15"+integerArrayList);
integerArrayList.removeIf(integer -> {
if (integer>17)
return true;
return false;
});
System.out.println("按自定义规则删除大于17的元素"+integerArrayList);
//更新元素
integerArrayList.set(0,100);
System.out.println("按索引0更新元素100"+integerArrayList);
//查询
System.out.println("查询索引10的元素"+integerArrayList.get(10));
System.out.println("查询元素16的索引"+integerArrayList.indexOf(16));
System.out.println("查询列表的长度"+integerArrayList.size());
}
}
底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList integerLinkedList=new LinkedList<>();
//增
for (int i = 0; i < 10; i++) {
integerLinkedList.add(i);
}
System.out.println("普通新增"+integerLinkedList);
integerLinkedList.addFirst(-1);
System.out.println("新增到头部"+integerLinkedList);
integerLinkedList.addLast(11);
System.out.println("新增到尾部"+integerLinkedList);
integerLinkedList.push(-2);
System.out.println("push到头部"+integerLinkedList);
System.out.println("-----------------------------------");
//删
System.out.println("remove删除头部元素"+integerLinkedList.remove());
System.out.println("pollFirst删除头部元素"+integerLinkedList.pollFirst());
System.out.println("remove删除索引为6的元素"+integerLinkedList.remove(6));
System.out.println("remove删除内容为11的元素"+integerLinkedList.remove(new Integer(11)));
System.out.println("pop删除头部元素"+integerLinkedList.pop());
System.out.println("pollLast删除尾部元素"+integerLinkedList.pollLast());
System.out.println("删除操作结束后的链表"+integerLinkedList);
System.out.println("-----------------------------------");
//改
integerLinkedList.set(2,33);
System.out.println("按索引2修改元素为33"+integerLinkedList);
System.out.println("-----------------------------------");
//查
System.out.println("链表大小"+integerLinkedList.size());
System.out.println("输出链表"+integerLinkedList);
System.out.println("查询首个元素但是不删除"+integerLinkedList.peekFirst());
System.out.println("查询最后一个元素但是不删除"+integerLinkedList.peekLast());
System.out.println("查询索引为3的元素"+integerLinkedList.get(3));
}
}
底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素
public class VectorDemo {
public static void main(String[] args) {
//Vector可以理解为ArrayList的线程安全的实现
Vector vector=new Vector<>();
//增
for (int i = 0; i < 10; i++) {
vector.add(i);
}
System.out.println("普通新增"+vector);
vector.add(2,12);
System.out.println("插入新增"+vector);
//删
vector.remove(new Integer(12));
System.out.println("按元素删除"+vector);
vector.remove(5);
System.out.println("按索引删除"+vector);
//改
vector.set(1,11);
System.out.println("按索引修改"+vector);
vector.setElementAt(111,1);
System.out.println("按索引修改无返回值"+vector);
//查
int val=vector.get(1);
System.out.println("按索引查询"+val);
System.out.println("查询数组长度"+vector.size());
System.out.println("查询数组容量"+vector.capacity());
}
}
继承自Vector,包含栈数据结构的操作,其中push和empty方法不是线程安全的,pop、peek、search方法是线程安全的。
public class StackDemo {
public static void main(String[] args) {
//Stack继承Vector,是一个栈结构类
Stack stack=new Stack<>();
//增
for (int i = 0; i < 10; i++) {
stack.push(i);
}
System.out.println("将元素压入栈"+stack);
//删
System.out.println("出栈一个元素"+stack.pop());
System.out.println("出栈另一个元素"+stack.pop());
//改
stack.set(3,33);
System.out.println("根据索引修改元素"+stack);
//查
System.out.println("获取栈顶元素"+stack.peek());
System.out.println("获取栈内元素数量"+stack.size());
System.out.println("获取站内某个索引的元素"+stack.get(3));
System.out.println("根据元素查从栈顶开始的序号"+stack.search(new Integer(2)));
}
}
Set中常用实现类包括HashSet、LinkedHashSet、TreeSet。它们底层都包含
HashSet中元素是无序的,底层是哈希表,无法通过索引检索其中存储的对象。
若两个元素的哈希值冲突了,那么在表中对应位置使用链表存储冲突的元素。
Set集合中不能插入相等的元素。
这里的相等是指对象的equals方法返回true,对于自己写的类,我们可以重写hashCode和equals方法,来自定义对象相等的判定条件,例如下面A类相等的条件就是两个对象id相等:
//使用id获取哈希值,在equals函数中最后以hashCode方法判定两个对象是否相等
class A{
private Integer id;
private String name;
public A(Integer id, String name) {
this.id = id;
this.name = name;
}
//如果id一样,则认为两个对象相等,否则不相等
@Override
public boolean equals(Object o) {
//若对象地址相等,返回true
if (this == o) return true;
//若对象类型不同,返回false
if (o == null || getClass() != o.getClass())
return false;
//若哈希值相等,返回true
A a = (A) o;
return this.hashCode()==o.hashCode();
}
@Override
public int hashCode() {
return Objects