集合类(上)

1.    集合类

先抛出一个问题:为什么要使用集合类,集合类有什么优点?
1、将数据封装成对象

2、将对象封装成集合

集合类有数组的几个地方:

[1].集合长度是可变的,而数组长度是固定.

[2].数组只能存放同一种类型的元素;

     集合的只要是对象就可以。

2.    集合类的体系结构

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└ Set

Map
├Hashtable
├HashMap
└WeakHashMap

实现Collection接口的:Set、List以及他们的实现类。

实现Map接口的:HashMap及其实现类。

我们常用的有Map及其实现类HashMap、HashTableList、Set及其实现类HashSet和ArrayList等。

下面的表格可以更直接的表现出他们之间的区别和联系:



3.    集合类的基本方法及使用重点

        简单的C、R、U和D四种操作就不一一明说,对几个比较重要的,常出错的,经常用到的进行说明与总结:
(1) 、集合中的迭代器
举例:使用集合的迭代器来迭代输出集合中的元素
public static void main(String[] args) {

		List c = new ArrayList();

		c.add("java1");
		c.add("java2");
		c.add("java3");

		Iterator it = c.iterator();

		while (it.hasNext()) {
			System.out.println(it.next());
		}

	}
输出结果:
java1
java2
java3
其中:

[1]. Iterator对象的获取方法

通过Collection接口的方法:Iterator<E> iterator();来获取具体容器类的内部类的对象。

[2]. 通过Iterator对象取出集合中元素的方式

Collection实现类迭代元素标准方式

 1. 先通过Iterator对象hasNext()方法进行元素是否存在的判断

 2. 通过Iterator对象next()方法对存在的元素进行取出

(2) 、迭代器容易出错的问题

   [1]. 代码

public static void addMethod(Collection al){	
	    Iterator it = al.iterator();  
	    System.out.println(al);
	    while(it.hasNext()){  
	        Object obj =it.next();  
	        if(obj.equals("java2")){  
	            al.add("java6");  
	        }  
	    }
	    System.out.println(al);
}
运行时,抛出异常:


问题分析:
1、异常产生的原因
if(obj.equals("java2")){  
al.add("java8");  
其中al存放了元素对象的引用,it也同样存放了对象元素的引用
所以,可以通过al来操作集合可以通过it来存取元素这样操作可能存在共享数据安全隐患
由上例可以看出不能通过Iterator这个类来实现边迭代边添加,而ListIterator可以解决这个问题。
(3) 、ListIterator

Iterator和ListIterator主要区别有:

一、ListIterator有add()方法,可以向List中添加对象,而Iterator不能。

二、ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历。但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

三、ListIterator可以定位当前的索引位置nextIndex()和previousIndex()可以实现。Iterator 没有此功能。

四、都可实现删除对象,但是ListIterator可以实现对象的修改set()方法可以实现。Iterator仅能遍历,不能修改。因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。

代码:

public class TestListIterator {

	public static void main(String[] args) {

		List<String> list = new ArrayList<String>();
		// 添加元素
		list.add("java1");
		list.add("java2");
		list.add("java3");
		list.add("java4");

		// 将该链接表转化为ListIterator
		ListIterator<String> li = list.listIterator();

		System.out.println(list);
		// 下面的代码进行ListIterator对象li的各种功能检测
		// 顺序输出迭代器中的元素
		while (li.hasNext()) {
			Object obj = li.next();
			if (obj.equals("java2")) {
				li.add("C++");
			}
		}
		// 输出添加数据后元素
		System.out.println(list);

		// 通过使用ListIterator的特有方法hasPrevious与previous实现List的元素
		// 逆序输出
		System.out.println("逆序输出");
		while (li.hasPrevious()) {
			System.out.print(li.previous().toString() + " ");
		}
		System.out.println();// 产生换行操作
		// 顺序输出li迭代器中现有的元素
		System.out.println("顺序输出");
		while (li.hasNext()) {
			System.out.print(li.next().toString() + " ");
		}
		System.out.println();// 产生换行操作
		System.out.println("通过使用ListIterator的set方法来改变li中的元素并顺序输出");
		// 通过使用ListIterator的set方法来改变li中的元素
		while (li.hasPrevious()) {
			String str = li.previous().toString();
			li.set(str.replaceAll("java", "java编号"));
		}
		// 顺序输出li迭代器中现有的元素
		while (li.hasNext()) {
			System.out.print(li.next().toString() + " ");
		}
	}
}
(4) 、 List接口常用实现子类ArrayList,Vector和LinkedList

  List接口一共有三个实现类,分别是ArrayList、Vector和LinkedList

  List用于存放多个元素,能够维护元素的次序,并且允许元素的重复。

  3个具体实现类的相关区别如下:

  [1]、ArrayList特点

       1、内部是通过数组实现的,

       2、适合随机查找和遍历不适合插入和删除

  [2]、LinkedList特点   

       1、内部是通过链表实现的,

       2、适合数据的动态插入和删除随机访问和遍历速度比较

  [3]、ArrayList与Vector的区别:

  其中Vector内部跟ArrayList一样,内部也是通过数组实现的。

  查看Java源代码,发现当数组的大小不够的时候,需要重新建立数组,然后将元素拷贝新的数组内,ArrayList和Vecto的数  组的大小不同

 ArrayList中:

public boolean add(E e) {
    ensureCapacity(size + 1);  // Increments modCount!!// 增加元素,判断是否能够容纳。不能的话就要新建数组
    elementData[size++] = e;
    return true;
}

/**
      * Increases the capacity of this <tt>ArrayList</tt> instance, if
       * necessary, to ensure that it can hold at least the number of elements
      * specified by the minimum capacity argument.
       *
       * @param   minCapacity   the desired minimum capacity */
     public void ensureCapacity(int minCapacity) {
     modCount++;
     int oldCapacity = elementData.length;
     if (minCapacity > oldCapacity) {
         Object oldData[] = elementData;
         int newCapacity = (oldCapacity * 3)/2 + 1;//增加新的数组的大小
             if (newCapacity < minCapacity)
         newCapacity = minCapacity;
             // minCapacity is usually close to size, so this is a win:
             elementData = Arrays.copyOf(elementData, newCapacity);
    }
}
Vector中:
private void ensureCapacityHelper(int minCapacity) {
     int oldCapacity = elementData.length;
     if (minCapacity > oldCapacity) {
         Object[] oldData = elementData;
         int newCapacity = (capacityIncrement > 0) ?
        (oldCapacity + capacityIncrement) : (oldCapacity * 2);
         if (newCapacity < minCapacity) {
           newCapacity = minCapacity;
         }
        elementData = Arrays.copyOf(elementData, newCapacity);
     }
}

总结:
ArrayList和Vector区别如下:
1.ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍
2.Vector提供indexOf(obj, start)接口,ArrayList没有。
3.Vector线程同步,效率低;而ArrayList线程不同步,效率高,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值