集合类
集合类似于保存一组对象的存储库,是用来存储和管理其他对象的对象,即对象的容器。它是Java中最重要的一种数据结构。和数组类似,一个集合中可以存放很多元素,但与数组不同的是集合的长度是可变的,而数组的长度是固定不变的;集合用来存放对象的引用,而数组用来存放基本类型的数据;集合可以存储多种类型的数据,而数组只能存储单一类型的元素。
下面来看看这些类及接口:
1、Collection接口
Collection接口中定义的方法
方法声明 | 方法功能 |
---|---|
boolean add(Object o) | 实现单元素的添加功能,先确定集合是否包含对象o,如果需要添加该对象则返回true。如果集合允许重复,add方法总是返回true。如果不允许重复,并已经有一个相等的元素在集合中,则add方法返回false |
boolean remove(Object o) | 该方法实现单元素的删除,如果集合中有与o相匹配的对象,则删除对象o,并返回true;反之返回false。如果o为null,并且集合中也有一个元素为null,也返回true |
boolean addAll(Collection c) | 将集合c中所有元素添加给该集合 |
void removeALL(Collection c) | 从集合中删除集合c中的所有元素 |
void retainAll(Collection c) | 从集合中删除集合c中不包含的元素 |
void clear() | 删除集合中所有的元素 |
int size() | 返回当前集合中元素的数量 |
boolean isEmpty() | 判断集合中是否有任何元素 |
boolean contains(Object o) | 查找集合中是否含有对象o |
boolean containsAll(Collection c) | 查找集合中是否含有集合c中所有元素 |
Iterator iterator() | 返回一个迭代器对象,用来访问集合中各个元素 |
Object[] toArray() | 返回一个内含集合所有元素的Object类型数 |
2、List接口及ArrayList、Vector类
List接口继承和扩展了Collection接口,List接口表示具有顺序的集合,其中可以包含重复元素。
List接口中声明的常用方法
方法声明 | 方法功能 |
---|---|
void add(int index, Object element) | 向列表的尾部追加指定的元素 |
Object remove(int index) | 移除列表中指定位置的元素 |
Object get(int index) | 返回列表中指定位置的元素 |
Object set(int index, Object element) | 用指定元素替换列表中指定位置的元素 |
int indexOf(Object o) | 返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回-1 |
int lastIndexOf(Object o) | 返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回-1 |
List接口的实现类主要有ArrayList、Stack、Vector和LinkedList
ArrayList类以数组为数据结构实现了List接口,用于表述长度可变的数组列表
ArrayList类中的常用方法
方法声明 | 方法功能 |
---|---|
public boolean add(E o) | 向ArrayList容器中添加元素,元素在ArrayList容器中的位置称作索引(Index)。第一个加入到容器中的对象得到索引值0,第二个对象的索引值是1,依此类推 |
public int size() | 获得ArrayList容器中元素的个数 |
public E get(int index) | 读取ArrayList容器对象的内容,通过ArrayList对象中元素的索引值获得容器中元素的对象 |
public E remove(int index) | 删除ArrayList容器对象,通过容器对象中元素的索引值,删除相应的元素 |
例:设计个人记事本程序,实现添加记录、显示记录内容和数量等功能。
import java.util.ArrayList;
import java.util.List;
public class Main{
private List<String> notes;
public Main() {
notes = new ArrayList<String>();
}
// 向记事本存储信息
public void storeNote(String note){
notes.add(note);
}
// 获得记事本中记录的数量
public int numberOfNotes(){
return notes.size();
}
// 读取记事本中指定的记录
public void showNote(int noteNumber){
if(noteNumber<0 || noteNumber>=numberOfNotes()){
// 错误处理
}else{
System.out.println(notes.get(noteNumber));
}
}
// 删除记事本中指定的记录
public void removeNote(int noteNumber){
if(noteNumber<0 || noteNumber>=numberOfNotes()){
// 错误处理
}else{
notes.remove(noteNumber);
}
}
}
Vector类也实现了List接口,也用于表述长度可变的对象数组列表。与ArrayList的差别是:Vector是同步(线程安全)的,运行效率较低,适合多线程;ArrayList是不同步的,适合单线程
Vector类中的常用方法
方法声明 | 方法功能 |
---|---|
public Vector() | 构造一个向量空间,使其内部数据数组的大小为10,其标准容量增量为0 |
public E elementAt(int index) | 返回指定索引处的组件。与get方法的功能完全相同 |
public void addElement(E obj) | 将指定的组件添加到此向量的末尾,将其大小增加1。若向量的大小比容量大,则增大其容量。与add方法的功能完全相同 |
public void removeElementAt(int index) | 删除指定索引的组件。此向量中的每个索引大于或等于指定index的组件都将下移,使其索引值比以前的值小1。此向量的大小将减1。索引必须为一个大于或等于0且小于向量当前大小的值。与remove方法的功能完全相同 |
public void insertElementAt(E obj, int index) | 将指定对象作为此向量中的组件插入到指定的index处。此向量中的每个索引大于或等于指定index的组件都将上移,使其索引值比以前的值大1.索引必须为一个大于或等于0且小于或等于向量当前大小的值。与add方法的功能完全相同 |
public boolean removeElement(Object obj) | 从此向量中移除变量的第一个匹配项。如果在此向量中找到该对象,那么向量中索引大于或等于该对象索引的的每个组件都会下移,使其索引值比以前小1。与remove方法的功能完全相同 |
public void removeAllElements() | 从此向量中移除全部组件,并将其大小设置为0.与clear方法的功能完全相同 |
public Object[] toArray() | 返回一个数组,包含此向量中以正确顺序存放的所有元素 |
堆栈是一种“后进先出”的数据结构,只能在一端进行输入或输出数据的操作
Stack类中的常用方法
方法声明 | 方法功能 |
---|---|
public Stack() | 创建一个空Stack |
public Object push(E item) | 把项压入栈顶 |
public Object pop() | 移除栈顶对象并作为此函数的值返回该对象 |
public Object peek() | 查看栈顶对象而不移除它 |
public boolean empty() | 测试堆栈是否为空 |
public int search(Obiect o) | 返回对象在栈中位置,以1为基数 |
Stack的使用示例:
import java.util.Stack;
public class Main{
public static void main(String[] args) {
Stack<String> s = new Stack<String>();
s.push("sun");
s.push("tree");
s.push("flower");
s.push("sky");
System.out.println("弹栈前:size=" + s.size());
System.out.println(s.pop());
System.out.println("弹栈后:size=" + s.size());
System.out.println(s.peek());
System.out.println("peek操作后:size=" + s.size());
while(!s.isEmpty())
System.out.println(s.pop());
}
}
LinkedList队列
LinkedList实现的是一个双向链表。每个节点除含有元素外,还包含向前、向后的指针。在链表结构中,每个元素都拥有两个指针属性,一个是指向上一个元素的previous指针,一个是指向下一个元素的next指针。增加节点,只会对链表的指针进行操作,速度快。
3、迭代器
Iterator及Enumeration
Iterator能够访问一个容器对象中的各个元素,而又不暴漏对象的内部细节。所有的Collection元素都可以用Iterator迭代器来获取元素,Vector等类还可以用Enumeration迭代器来列举元素。
4、Map接口及HashTable类
Map接口提供将键映射至值的功能,每个键最多只能映射一个值
Map接口中的常用方法
方法声明 | 方法功能 |
---|---|
Object put(Object key, Object value) | 将指定的值与此映射中的指定键相关联。如果此映射中以前包含一个该键的映射关系,则用指定值替换旧值 |
Object get(Object key) | 返回此映射中映射到指定键的值 |
Object remove(Object key) | 如果存在此键的映射关系,则将其从映射中移除 |
boolean isEmpty() | 如果此映射未包含键-值映射关系,则返回true |
void clear() | 从此映射中移除所有映射关系 |
int size() | 返回此映射中的键-值映射关系数 |
boolean containsKey(Object key) | 如果此映射包含指定键的映射关系,则返回true |
boolean containsValue(Object value) | 如果此映射为指定值映射一个或多个键,则返回true |
Set keySet() | 返回此映射中包含的键的Set视图 |
Collection value() | 返回此映射中包含的值的Collection视图 |
HashMap的使用示例:
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
public class Main{
public static void main(String[] args) {
HashMap<Integer, String> hm = new HashMap<>();
hm.put(1, "sun");
hm.put(2, "tree");
hm.put(3, "flower");
hm.put(4, "sky");
System.out.println("--------检索单个元素--------");
System.out.println(hm.get(3));
System.out.println("--------遍历所有\"键\"--------");
Set key = hm.keySet();
for (Object object : key) {
System.out.println(object);
}
System.out.println("--------遍历所有\"值\"--------");
Collection value = hm.values();
for (Object object : value) {
System.out.println(object);
}
}
}
HashMap和HashTable
HashMap是基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。除了不同步和允许使用null之外,与HashTable类大致相同。HashTable类实现一个哈希表,该哈希表将键映射到相应的值。任何非null对象都可以用作键或值。
Set接口和其实现类
Set接口的实现类的共同特点是不允许重复元素存在。Set接口的实现类主要有HashSet和TreeSet类。
HashSet是无序集合的类,使用哈希表实现,因操作速度快,比较适用于内容规模较大的元素。
TreeSet是有序的集合类,采用平衡二叉树的实现方式,操作速度较慢