---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
java是一门面向对象的语言,而集合就是存储对象的容器.
集合分为单列集合和双列集合,今天的重点是堆单列集合的学习.
单列集合的根接口是Collection,它有2个子接口,分别是List和Set,要对其进行操作就要找对它实现的子类.List的常用子类主要有三个,分别是ArrayList,LinkedList和Vector,Set的主要常用子类有HashSet和TreeSet,
现在从Lis开始解析.List接口中的集合是有序的,它出继承父类Collection的方法外,也有自己的一些特有方法,如添加void list.add(index,String item),删除Object list.remove(int index)功能等,其中最特殊的是迭代ListIterator()方法.因为Iterator里没有add()添加方法,如果添加用容器里的里的add方法添加的话,可能会出现并发修改异常---ConcurrentModificationE-xception如代码:
Iterator it = list.iterator();
while(it.hasNext()){
String s = (String)it.next();
if(s.equals("abc2"))
list.add("aaa");
System.out.println("s="+s);
}
System.out.println(list);
为解决这个问题,于是有了列表迭代器,里面定义了自己的增加删除操作,避免异常.
ArrayList,底层是数组结构,不同步,因此对数据的查找很快,但是增删较慢,里面可以存重复元素,为更好的理解ArrayList方法,模拟了底层的一些方法:
public class MyArrayListDemo2 {
/* ArrayList的主要方法
* void add(Object obj);
Object get(int index);
int size();
void add(int index, Object obj);
void set(int index, Object obj);
void remove(int index);
void remove(Object obj);
*/
private Object[] arr = new Object[10]; //定义一个容量为10的数组
private int size; //元素个数,可以用来判断长度
public void add(Object obj) { //添加方法
if(size == arr.length) {//判断容量
Object[] newArr = new Object[arr.length + (arr.length >> 1)]; //创建一个新数组,增加50%的容量
System.arraycopy(arr, 0, newArr, 0, arr.length); //用新数组覆盖老数组
arr = newArr; //将老数组指向新数组
}
arr[size++] = obj;
}
public Object get(int index) { //获取方法
if(index >= size || index < 0) {//对边界进行判断
throw new IndexOutOfBoundsException("Index:" +index + ",Size:" +size); //抛异常
}
return arr[index];
}
public int size() {
return size; //返回元素个数
}
public void add(int index, Object obj) { //在指定的角标添加对象
if(index >= size || index < 0) {//对边界进行判断
throw new IndexOutOfBoundsException("Index:" +index + ",Size:" +size);
}
if(size == arr.length) {//对容量判断
Object[] newArr = new Object[arr.length + (arr.length >> 1)];
System.arraycopy(arr, 0, newArr, 0, arr.length);
arr = newArr;
}
System.arraycopy(arr, index, arr, index + 1, size - index); //对原数组进行操作,
arr[index] = obj;
size++;
}
public void set(int index, Object obj) {
if(index >= size || index < 0) {//对边界判断
throw new IndexOutOfBoundsException("Index:" +index + ",Size:" +size);
}
arr[index] = obj;
}
public void remove(int index) {
if(index >= size || index < 0) {//对边界判断
throw new IndexOutOfBoundsException("Index:" +index + ",Size:" +size);
}
int numMove = size - index - 1;
if(numMove > 0) {
System.arraycopy(arr, index + 1, arr, index,numMove);
}
arr[--size] = null;
}
public void remove(Object obj) {
for(int x = 0; x < size; x++) {
if(arr[x].equals(obj)) {
remove(x--); //移除后,指针向下移动,数组元素向上移动,因此没移除一次对x-1
//return;
}
}
}
}
LinkedList底层是链表结构,因此对数据增删较快,查找较慢,特有的方法有addFrist-(),addLast(),getFrist(),getLast()-,removeFrist(),removeFirst(),removeLast(),利用这些方法可以模拟堆栈结构和队列结构,代码如下:
public class Stack<E> {
private LinkedList<E> list; //定义一个LinkedList类型的引用
public Stack() { //定义本类的构造函数
list = new LinkedList<>();
}
public void set(E e) { //封装方法
list.addLast(e); //将元素从前往后添加
}
public E get() {
return list.removeLast(); //将元素从后往前移除
}
public boolean isEmpty() {
return list.isEmpty(); //判断是否为空
}
}
Vector,底层是数组结构,版本是1.0的,早于List(1.2),由于它是同步的,因此无论查找还是添加都相对慢,基本上已经被ArrayList替代.但它有个枚举的功能,elements()方法.
单列集合另一个接口Set是无序的,该接口的方法与Collection方法一致
它的一个子类是HashSet,底层的数据结构是hash表,比较的方式是先比较hash值是否相同,相同则再比较equals是否相同,相同则判断为相同.TreeSet是二叉树结构,判断效率较高,按字典顺序比较.
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------