您的位置:首页 > 编程语言 > Java开发

Java_List_ArrayList,Vector,LinkedList(含Enumeration枚举应用)

2013-04-28 10:06 531 查看
本博客为子墨原创,转载请注明出处!
http://blog.csdn.net/zimo2013/article/details/8862177

 

1.List的子类

        (1).ArrayList

              底层的数据结构是数组,线程不同步,ArrayList替代了Vector,查询元素的速度非常快,允许null的元素。它的实现不是synchronized的,如果多个线程访问一个ArrayList实例,并且至少有一个会对它进行修改的话,就必须对它使用外部synchronized

       (2).LinkedList

              底层的数据结构是链表,线程不同步,增删元素的速度非常快,查询慢。不允许出现null,否则会报NoSuchElementException异常。

       (3).Vector

              底层的数据结构就是数组,线程同步的,Vector无论查询和增删都慢,在不考虑线程同步时,被ArrayList替代。

2.ListIterator迭代器

       ListIterator合适于双向遍历List集合,该迭代器包含较多操作集合的方法

//去除重复元素
import java.util.*;
class Person
{
private String name;
private int age;
Person(String name, int age)
{
this.name = name;
this.age = age;
}
public int getAge()
{
return this.age;
}
public String getName()
{
return this.name;
}
public boolean equals(Object obj)
{
if (!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.getName()) && this.age==p.getAge();
}
}
class Demo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();

al.add(new Person("java01", 11));
al.add(new Person("java02", 22));
al.add(new Person("java03", 33));
al.add(new Person("java03", 33));
al.add(new Person("java04", 44));

al = noRepeat(al);
Iterator it = al.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
sop("Name:" + p.getName() +"  Age:"+ p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
public static ArrayList noRepeat(ArrayList a1)
{
ArrayList a = new ArrayList();
Iterator it = a1.iterator();
while(it.hasNext())
{
Object p = it.next();
if(!a.contains(p))	//判断ArrayList是否存在一个元素contains(),必须做的一个动作即使用元素的equals()方法
a.add(p);	//ArrayList的contains动作隐含了元素的equals
}

return a;
}
}

 

/*
Vector 枚举应用
Strawberry2013-5-4
*/
import java.util.*;

class PrintStreamDemo
{
public static void main(String[] args)
{
Vector<String> v = new Vector<String>();
v.add("aaaaaa");
v.add("BBBBBBB");
v.add("aaa");

Enumeration e = v.elements();
while(e.hasMoreElements())
{
System.out.println(e.nextElement());
}
}
}


3.在Iterator中操作List抛出ConcurrentModificationException

      对ArrayList的操作我们可以通过索引象来访问,也可以通过Iterator来访问,只要不对ArrayList结构上进行修改都不会造成ConcurrentModificationException,单独用索引对ArrayList进行修改也不会造成该问题,造成该问题主要是在索引和Iterator混用。可以通过JDK的源码来说明该问题。

/**
*在Iterator的内部有个expectedModCount 变量,
*该变量每次初始化*Iterator的时候等于ArrayList的modCount,modCount记录了对ArrayList的结构修改次数,
*在通过Iterator对ArrayList进行结构的修改的时候都会将expectedModCount 与modCount同步,
*但是如果在通过Iterator访问的时候同时又通过索引的方式去修改ArrayList的结构的话,
*由于通过索引的方式只会修改modCount不会同步修改expectedModCount 就会导致
*modCount和expectedModCount 不相等就会抛ConcurrentModificationException,
*这也就是Iterator的fail-fast,快速失效的。所以只要采取一种方式操作ArrayList就不会出问题,
*当然ArrayList不是线程安全的,此处不讨论对线程问题。
*
*/
int expectedModCount = modCount;
public E next() {
checkForComodification();//判断modeCount与expectedModCount 是否相等,如果不相等就抛异常
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}

public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();//同样去判断modeCount与expectedModCount 是否相等

try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;//此处修改ArrayList的结构,所以要将expectedModCount 于modCount同步,主要是AbstractList.this.remove(lastRet);的remove方法中将modCount++了,导致了modCount与expectedModCount 不相等了。
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}

//判断modCount 与expectedModCount是否相等,如果不相等就抛ConcurrentModificationException异常
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐