集合一:Collection、Iterator、List、ArrayList、Vector、LinkedList
2014-02-21 13:00
337 查看
1 集合
1.1 集合概述
集合是用来存储对象,并对多个对象进行操作的容器。集合和数组都可以存储对象,但集合长度是可变的,而数组长度是固定的。
数组还可以存储基本数据类型,而集合只能存储对象。
实际上存放的是对象的引用(内存地址)。
Java中的集合框架:
Collection接口有两个子接口:List和Set。
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。线程不同步
|--LinkedList:底层使用的链表数据结构。特点:查询速度很慢,增删速度快。
|--Vector:底层是数组数据结构。功能与ArrayList相同,但是线程同步。被ArrayList替代(多线程加锁)
|--Set:元素是无序的,元素不可以重复。无序:存入和取出的顺序不一定一致。
|--HashSet:数据结构是哈希表,线程是非同步的。保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals()方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。保证元素唯一性的依据:compareTo()方法的return 返回值是0,即: return 0;
1.2 集合Collection共性方法
1,boolean add(e):将指定的元素添加到此列表的尾部,即添加一个对象到集合尾部,e是要添加到此列表中的元素(任意类型),返回true。
2,boolean remove(Object o):
移除此列表中首次出现的指定元素(如果存在)。如果此列表包含指定的元素,则返回true。
3,void clear():
移除此列表中的所有元素。
4,int size():
返回此列表中的元素数,即集合中对象的个数。
5,boolean contains(Object o):
如果此列表中包含指定元素,则返回true,即如果此集合中包含o这个元素,则返回true。
6,boolean isEmpty():
如果此列表没有元素,返回true,即是个空的集合,返回true。
7,boolean retainAll(Collection c):
移除当前集合中未包含在集合c中的所有元素,取交集。如果当前集合因为调用发生更改,则返回true。
8,boolean removeAll(Collection c):
移除当前集合中,两个集合的交集,即去掉交集。如果当前集合因为调用发生更改,则返回true。
9,boolean containsAll(Collection c):
如果当前集合包含集合c中的所有元素,则返回true。
10,boolean addAll(Collection c):
将集合c添加到当前集合的尾部,如果当前集合因为调用发生更改,则返回true。
1.3 迭代器Iterator
什么是迭代器呢?其实就是集合的取出元素的方式,用来操作集合。
Iterator<T> iterator();
Iterator接口:把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内容的元素,那么取出方式就被定义成了内部类。
而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容(判断和取出),把共性内容封装为Iterator接口。
那么如何获取集合的取出对象呢? 通过一个对外提供的方法 iterator();
Iterator it = collection.iterator();
boolean hasNext();
Object next();
void remove();
集合共性方法和迭代器示例:
import java.util.*; class CollectionDemo{ public static void main(String[] args){ method_3(); } public static void sop(Object obj){ System.out.println(obj); } public static void method_1(){ //创建一个集合容器,使用Collection接口的子类。ArrayList ArrayList al = new ArrayList(); //1,添加元素 al.add("java01"); //add(Object obj); al.add("java02"); al.add("java03"); al.add("java04"); //打印原集合 sop(al); //3,删除元素 al.remove("java02"); al.clear(); //清空集合 //4,判断元素 sop("java03是否存在:"+al.contains("java03")); sop("集合是否为空:"+al.isEmpty()); //2,获取个数,集合长度。 sop("size=:"+al.size()); //集合的size()代替了length(),获取长度 sop(al); } public static void method_2(){ ArrayList al1 = new ArrayList(); al1.add("java01"); al1.add("java02"); al1.add("java03"); al1.add("java04"); ArrayList al2 = new ArrayList(); al2.add("java03"); al2.add("java04"); al2.add("java05"); al2.add("java06"); al1.retainAll(al2); //取交集,al1中只会保留和al2中相同的元素。 sop("al1:"+al1); sop("al2:"+al2); } public static void method_3(){ //迭代器 ArrayList al3 = new ArrayList(); al3.add("java01"); al3.add("java02"); al3.add("java03"); al3.add("java04"); Iterator it = al3.iterator(); while(it.hasNext()){ sop(it.next()); } /* 节约内存的写法,循环结束 it对象即消亡 for(Iterator it = al3.iterator(); it.hasNext(); ){ sop(it.next()); } */ } }
2 List集合
List是Collection接口的一个子接口,List集合也是集合的一种。|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。线程不同步。
|--LinkedList:底层使用的链表数据结构。特点:查询速度很慢,增删速度快。
|--Vector:底层是数组数据结构。功能与ArrayList相同,但是线程同步。被ArrayList替代(多线程加锁)。
2.1 List集合的特有方法
List集合特有方法:凡是可以操作脚标index的方法都是该体系特有的方法。增:
add(index,element):在集合的index位置(脚标)添加元素。
addAll(index,Collection):在集合的index位置(脚标)添加一个集合。
删:
remove(index):删除集合中位置index上的元素。
改:
set(index,element):修改集合index位置上的元素为element。
查:
get(index):获取指定位置上的元素。
subList(from,to):获取从from位置到(to-1)位置上的子集合,包括首不包括尾。
listIterator():获取ListIterator迭代器,ListIterator是Iterator的子接口,是List集合特有的迭代器。
2.2 List集合特有迭代器ListIterator
List集合特有的迭代器,ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常:ConcurrentModificationException。
所以在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断、取出、删除的操作。
如果想要其他的操作如添加、修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。
List集合特有方法的代码示例:
import java.util.*; class ListDemo{ public static void main(String[] args){ method_ListIterator(); } public static void sop(Object obj){ System.out.println(obj); } public static void method(){ ArrayList al1 = new ArrayList(); //创建集合容器 al1.add("java01"); //添加元素 al1.add("java02"); al1.add("java03"); al1.add("java04"); sop("原集合是:"+al1); al1.add(1,"java05"); //增:在指定位置添加元素 al1.remove(2); //删:删除指定位置的元素 al1.set(2,"java007"); //改:修改元素 sop(al1); sop("get(1):"+al1.get(1));//查:获取指定元素 for(int x=0; x<al1.size(); x++){ //获取全部元素 sop("al1("+x+"):"+al1.get(x)); } for(Iterator it=al1.iterator(); it.hasNext(); ){ //迭代获取全部 sop(it.next()); } //通过indexOf()获取对象的位置 sop("java007位置:"+al1.indexOf("java007")); List sub = al1.subList(1,3); //包括首,不包括尾 sop("sub:"+sub); } public static void method_Iterator(){ ArrayList al2 = new ArrayList(); //创建集合容器 al2.add("java01"); //添加元素 al2.add("java02"); al2.add("java03"); sop("原集合是:"+al2); Iterator it = al2.iterator(); while(it.hasNext()){ Object obj = it.next(); if(obj.equals("java02")) //al2.add("java08"); 并发异常,集合和迭代器不能同时操作 it.remove(); //将java02的引用从集合中删除了,但对象还在内存中 sop("obj="+obj); } sop(al2); } public static void method_ListIterator(){ ArrayList al3 = new ArrayList(); //创建集合容器 al3.add("java01"); //添加元素 al3.add("java02"); al3.add("java03"); sop("原集合是:"+al3); ListIterator li = al3.listIterator(); //获取ListIterator迭代器。 while(li.hasNext()){ Object obj = li.next(); if(obj.equals("java02")) li.add("java008"); //set,remove } sop(al3); } }
2.3 ArrayList集合
ArrayList集合底层的数据结构使用的是数组结构。特点:查询速度快,但是增删很慢。
ArrayList是线程不同步。
ArrayList拥有Collection集合中的共性方法,以及List集合的特有方法。
代码示例可以参考本文第一段代码Demo。
2.4 Vector集合
Vector类是List接口的子类,当然也实现了集合Collection接口。Vector集合的底层数据结构是数组。功能与ArrayList相同,但是Vector线程同步。
可以被ArrayList替代(多线程加锁后)。
Vector中的枚举:
枚举就是Vector特有的取出方式。
枚举和迭代器很像,其实枚举和迭代器是一样的。
因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。
(优先考虑Iterator接口,而不是Enumeration。)
Vector代码示例:
import java.util.*; class VectorDemo{ public static void main(String[] args){ Vector v = new Vector(); v.add("java01"); v.add("java02"); v.add("java03"); v.add("java04"); Enumeration en = v.elements(); //Vector的elements方法返回一个枚举 while(en.hasMoreElements()){ //hasMoreElements是否有更多元素 System.out.println(en.nextElement()); //nextElement返回下一个元素 } } }
2.5 LinkedList集合
LinkedList集合底层使用的是链表数据结构。特点:查询速度很慢,增删速度快。
LinkedList集合特有方法:
addFirst():在头部添加一个元素。
addLast():在尾部添加一个元素。
getFirst():get获取元素但不删除元素,获取列表第一个元素。
getLast():获取列表末尾的元素。
removeFirst():获取并且删除第一个元素。
removeLast():获取并且删除最后一个元素。
如果get、remove时,列表为空没有元素,抛出NoSuchElementException异常。
在JDK1.6中出现了替代方法(替代列表为空时抛出异常):
offerFirst():offer替代了add,在此列表的开头插入指定的元素。
offerLast():在此列表末尾插入指定的元素。
peekFirst():peek替代了get,获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
peekLast():获取但不移除此列表的最后一个元素;如果此列表为空,则返回 nul。
pollFirst():poll替代了remove,获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
pollLast():获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
如果peek、poll时,列表为空没有元素,不再抛出异常,而是返回null。
LinkedList集合的代码示例:
import java.util.*; class LinkedListDemo{ public static void main(String[] args){ LinkedList link = new LinkedList(); link.addLast("java01"); link.addLast("java02"); link.addFirst("java03"); link.addFirst("java04"); sop(link); sop(link.getFirst()); //获取第一个元素 sop(link.getLast()); sop("size="+link.size()); sop(link.removeFirst()); //获取并删除第一个元素 sop("size="+link.size()); while(!link.isEmpty()){ //使用LinkedList特有方法,相当于迭代器Iterator sop(link.removeFirst()); } } public static void sop(Object obj){ System.out.println(obj); } }
3 集合的小练习
3.1 LinkedList集合的练习
LinkedList集合的一个小练习,要求掌握。需求:使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出。
队列:先进先出。
LinkedList练习的代码示例:
import java.util.*; class LinkedListTest{ public static void main(String[] args){ DuiZhan d = new DuiZhan(); //堆栈 d.myAdd("java01"); d.myAdd("java02"); d.myAdd("java03"); d.myAdd("java04"); sop(d); while(!d.isNull()){ sop(d.myGet()); } } public static void sop(Object obj){ System.out.println(obj); } } class DuiLie{ //模拟队列,先进先出。 LinkedList link; DuiLie(){ link = new LinkedList(); } public void myAdd(Object obj){ //队列中在末尾添加元素。 link.addLast(obj); } public Object myGet(){ //队列中在头部删除元素。 return link.removeFirst(); } public boolean isNull(){ return link.isEmpty(); } } class DuiZhan{ //模拟堆栈,先进后出。 LinkedList link; DuiZhan(){ link = new LinkedList(); } public void myAdd(Object obj){ //堆栈中在末尾添加元素。 link.addLast(obj); } public Object myGet(){ //堆栈中在末尾删除元素。 return link.removeLast(); //这里与队列不同 } public boolean isNull(){ return link.isEmpty(); } }
3.2 ArrayList集合的练习1
需求:去除ArrayList集合中的重复元素。死路:定义一个新集合,遍历原集合的元素,如果新集合中没有此元素,则不重复,添加。如果新集合中已有此元素,则重复,不添加。
代码示例:
import java.util.*; class ArrayListTest{ public static void main(String[] args){ ArrayList al = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java01"); al.add("java02"); al.add("java03"); sop(al); al = singleElement(al); //去除重复元素 sop(al); Iterator it = al.iterator(); //迭代循环中next调用一次,就要hasNext判断一次。 while(it.hasNext()){ sop(it.next()); //sop(it.next()+"..."+it.next()); //不能一次循环调用两次next(); } } public static void sop(Object obj){ System.out.println(obj); } public static ArrayList singleElement(ArrayList al){ //实现功能:去除重复元素 ArrayList newAl = new ArrayList(); //定义一个临时容器,存储结果集合 /* 如果新集合中没有此元素,则不重复,添加。 如果新集合中已有此元素,则重复,不添加。 */ Iterator it = al.iterator(); while(it.hasNext()){ Object obj = it.next(); if(!newAl.contains(obj)) newAl.add(obj); } return newAl; } }
3.3 ArrayList集合的练习2
需求:将自定义对象作为元素存到ArrayList集合中,并去除重复元素。比如:存人对象。同姓名同年龄,视为同一个人,为重复元素。
思路:
1,对人进行描述,将数据封装进人对象。
2,定义容器,将人存入。
3,取出。
注意:List集合判断元素是否相同,依据是元素的equals()方法,即Object父类的equals()方法,有时需要重写equals(),contains()、remove()都依赖equals()方法。
代码示例(主要集合中的多态:add()中添加的是Object类型,如果要用自定义方法,需向下转型):
import java.util.*; class ArrayListTest2{ public static void main(String[] args){ ArrayList al = new ArrayList(); al.add(new Person("lisi01",30)); //al.add(Object,obj); //Object obj = new Person("lisi01",30); al.add(new Person("lisi02",32)); al.add(new Person("lisi02",32)); al.add(new Person("lisi03",36)); ///sop(al); al = singleElement(al); //去除重复元素 Iterator it = al.iterator(); while(it.hasNext()){ Object obj = it.next(); Person p = (Person)obj; //next得到的是Object类型,向下转型为Person,才能调用Person自定义方法 sop(p.getName()+"..."+p.getAge()); } } public static void sop(Object obj){ System.out.println(obj); } public static ArrayList singleElement(ArrayList al){ //实现功能:去除重复元素 ArrayList newAl = new ArrayList(); //定义一个临时容器,存储结果集合 Iterator it = al.iterator(); while(it.hasNext()){ Object obj = it.next(); if(!newAl.contains(obj)) //Collection接口中contains()的原理就是equals(); newAl.add(obj); } return newAl; } } class Person{ private String name; private int age; Person(String name,int age){ this.name = name; this.age = age; } public String getName(){ return name; } public int getAge(){ return age; } public boolean equals(Object obj){ //重写equals(),自定义两个对象相同的规则,用来去重。 if(!(obj instanceof Person)) return false; Person p = (Person)obj; System.out.println(this.name+"..."+p.name); return this.name.equals(p.name) && this.age == p.age; } }
相关文章推荐
- AVG 7.5.1.43 版本 序列号 集合
- SQL Server游标的使用/关闭/释放/优化小结
- C#中Ilist与list的区别小结
- C#中IList<T>与List<T>的区别深入解析
- JavaScript Archive Network 集合
- javascript radio list的实现细节(多浏览器兼容)
- jQuery学习7 操作JavaScript对象和集合的函数
- 网页代码常用小技巧总结第1/3页
- c++ STL容器总结之:vertor与list的应用
- 详解JAVA高质量代码之数组与集合
- 基于Java回顾之集合的总结概述
- 探讨:如何使用委托,匿名方法对集合进行万能排序
- 大家注意vector, list, set, map成员函数erase
- ASP.NET―001:GridView绑定List、页面返回值具体实现
- JavaScript中的集合及效率
- List all the Databases on a SQL Server
- C#各种集合操作的性能总结
- js Map List 遍历使用示例
- java中vector与hashtable操作实例分享
- 【Python之旅】第二篇(七):集合