java集合的学习

来源:互联网 发布:git linux设置ignore 编辑:程序博客网 时间:2024/05/30 12:31
   

java.util包中包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式。

接口:Collection

Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。

所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。

主要的一个接口方法:boolean add(Ojbect c) 
虽然返回的是boolean,但不是表示添加成功与否,这个返回值表示的意义是add()执行后,集合的内容是否改变了(就是元素的数量、位置等有无变化)。类似的addAll,remove,removeAll,remainAll也是一样的。

用Iterator模式实现遍历集合:Collection有一个重要的方法:iterator(),返回一个Iterator(迭代器),用于遍历集合的所有元素。Iterator模式可以把访问逻辑从不同的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。典型的用法如下:由Collection接口派生的两个接口是List和Set。

List接口:List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。和下面要提到的Set不同,List允许有相同的元素。

除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。

LinkedList类

LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。

package test;import java.awt.List;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Collection;import java.util.Collections;import java.util.Date;import java.util.Iterator;import java.util.LinkedList;public class test3{LinkedList list=new LinkedList();Object object=new Object();public test3(){int a[]=new int[10];for(int i=0;i<10;i++)list.add(i+"");/*System.out.println(list.getFirst());System.out.println(list.getLast());System.out.println(list.getClass());System.out.println(list.get(9));System.out.println(list.remove(0));*/}public void Bianli(){synchronized(object){Iterator it=list.iterator();//获得一个迭代器while(it.hasNext()){// 得到下一个元素System.out.println(it.next());} }}public static void main(String args[]){  test3 p=new test3();   p.Bianli();}}


注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List: 
List list = Collections.synchronizedList(new LinkedList(…));

线程安全:比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。

在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;

而如果是在多线程情况下,比如有两个线程,线程 A 先将元素1存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B向此 ArrayList 添加元素2,因为此时 Size 仍然等于 0 (注意,我们假设的是添加一个元素是要两个步骤,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值,结果Size都等于1。

那好,我们来看看 ArrayList 的情况,期望的元素应该有2个,而 实际元素是在0位置,造成丢失元素,故Size 等于 1。这就是"线程不安全"了。



1 0
原创粉丝点击