数据结构=数据+结构,是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
Java集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等。
Collection接口:
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”——如List和Set。
表(List)
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。实现List接口的常用类有线性表(ArrayList),链表(LinkedList),Vector和堆栈(Stack)。
线性表(ArrayList)
线性表是最常用且最简单的一种数据结构,它是n个数据元素的有限序列。实现线性表的方式一般有两种,一种是使用数组存储线性表的元素,即用一组连续的存储单元依次存储线性表的数据元素。另一种是使用链表存储线性表的元素,即用一组任意的存储单元存储线性表的数据元素(存储单元可以是连续的,也可以是不连续的)。
下面是用数组实现线性表的代码:
public class MyArrayList<AnyType> implements Iterable {
private static final int DEFAULT_CAPACITY = 10; // 设置线性表默认长度为10
private int theSize;
private AnyType[] theItems;
public int capacity=0;
public MyArrayList() {
clear();
}
public void clear() {
theSize = 0;
ensureCapacity(DEFAULT_CAPACITY);
}
public boolean isEmpty() {
return size() == 0;
}
public void trimToSize() {
ensureCapacity(size());
}
public AnyType get(int idx) {
if (idx < 0 || idx >= size()) {
System.out.println("第"+idx+"个元素"+"不在线性表范围内!");
}
return theItems[idx];
}
public AnyType set(int idx, AnyType newVal) {
if (idx < 0 || idx >= size()) {
System.out.println("第"+idx+"个元素"+"不在线性表范围内!");
}
AnyType old = theItems[idx];
theItems[idx] = newVal;
return old;
}
@SuppressWarnings("unchecked")
private void ensureCapacity(int newCapacity) {
if (newCapacity < theSize) {
return;
}
capacity=newCapacity;
AnyType[] old = theItems;
theItems = (AnyType[]) new Object[newCapacity];
for (int i = 0; i < size(); i++) {
theItems[i] = old[i];
}
}
public boolean add(AnyType x) {
add(size(), x);
return true;
}
private void add(int idx, AnyType x) {
if (theItems.length == size()) {
ensureCapacity(capacity+10);
}
for (int i = theSize; i > idx; i--) {
theItems[i] = theItems[i - 1];
}
theItems[idx] = x;
theSize++;
}
public AnyType remove(int idx) {
AnyType removedItem = theItems[idx];
for (int i = idx; i < size() - 1; i++) {
theItems[i] = theItems[i + 1];
}
theSize--;
return removedItem;
}
public int size() {
return theSize;
}
@Override
public Iterator<AnyType> iterator() {
return new ArrayListIterator();
}
// 嵌套类,实现迭代器的功能
public class ArrayListIterator implements Iterator<AnyType> {
private int current = 0;
@Override
// 判断线性表是否存在下一项
public boolean hasNext() {
return current < size();
}
@Override
// 读取线性表的下一项
public AnyType next() {
if (!hasNext()) {
System.out.println("下一项不存在!!!");
}
return theItems[current++];
}
// 删除线性表的此项
public void remove() {
MyArrayList.this.remove(--current);
}
}
}
在MyArrayList类中嵌套了一个ArrayListIterator类,继承迭代器接口Iterator,实现线性表的迭代读取和删除操作。