java基础之集合

 Java 的集合类它可以存储数量不等的多个对象. 或者也可以理解为特殊的容器(如前面学过的数组,集合的功能要更为强大)

Java集合大致分为三大类 Set list Map三类体系 其中Set代表无序不可以重复的集合,List代表有序的重复的集合,Map代表具有映射关系的集合。jdk1.5增加了Queue体系的集合 代表队列集合的实现。 Java的集合类主要由两个接口派生出:Cllection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。 一 Colllection和Iterator接口 Collcetion接口是List Se和Queue接口的父亲接口,该接口定义的方法能操作这三个集合元素,Cllection接口定义了如下操作集合的元素的方法 1 boolean add(Object o):该方法用于向集合里添加一个元素,如果集合对象被添加操作改变了则返回true; 2 boolean addAll(Collection c):该方法把集合里所有的元素添加到指定的集合里,如果集合对象被添加操作改变了则返回true; 3 void clear():清除集合里所有的元素,使集合的长度变为0; 4 boolean contains(Object o):返回集合里是否包含指定的元素;   5 boolean containsAll(Cllocetion c)返回集合里是否包含集合c的全部元素; 6 boolean isEmpty() 返回集合是否为空,当集合长度为0返回true;   7 Iterator iterator():返回iterator对象遍历集合;   8 boolean remove(Object o)删除集合中指定的元素o,如果有多个o元素这些元素将都被删除; 9 boolean remove (Collection c):从集合中删除集合c里指定的全部元素;   10 int size():返回集合里所有元素的个数;   11 Object[]toArray() 把集合转换为数组,集合的元素变成对应的数组元素; 下面是测试这些方法的简单代码: import java.util.*; public class TestCollection { public static void main(String[] args) { Collection c = new ArrayList(); //添加元素   c.add("swk");   //虽然集合里不能放基本类型的值,但Java支持自动装箱   c.add(6);   System.out.println("c集合的元素个数为:" + c.size()); //删除指定元素   c.remove(6);   System.out.println("c集合的元素个数为:" + c.size()); //判断是否包含指定字符串   System.out.println("c集合的是否包含孙悟空字符串:" + c.contains("swk")); c.add("J2EE企业应用实战");   System.out.println("c集合的元素:" + c);   Collection books = new HashSet();   books.add("轻量级J2EE企业应用实战");   books.add("Struts2权威指南");   System.out.println("c集合是否完全包含books集合?" + c.containsAll(books));   //用c集合减去books集合里的元素   c.removeAll(books);   System.out.println("c集合的元素:" + c);   //删除c集合里所有元素   c.clear();   System.out.println("c集合的元素:" + c);   //books集合里只剩下c集合里也同时包含的元素   books.retainAll(c);   System.out.println("books集合的元素:" + books); } } 使用Iterator 接口遍历集合 Iterator接口也是java集合框架的成员与其他集合不一样,该集合是用来遍历集合元素的 Iterator对象也被称为迭代器; Iterator接口提供了下面主要的三个方法 boolean hasNext();如果迭代的集合还有没遍历的则返回true; boolean next()返回集合里下一个元素; void remove()删除集合里上一次next方法返回的元素; 参考代码: public class TestIterator { public static void main(String[] args) {   //创建一个集合   Collection books = new HashSet();   books.add("轻量级J2EE企业应用实战");   books.add("Struts2权威指南");   books.add("基于J2EE的Ajax宝典");   //获取books集合对应的迭代器   Iterator it = books.iterator();   while(it.hasNext())   {     String book = (String)it.next();     System.out.println(book);   if (book.equals("Struts2权威指南"))   {     it.remove();   }   //对book变量赋值,不会改变集合元素本身   book = "测试字符串"; }   System.out.println(books); } } 注意迭代器在迭代集合的过程中如果发现集合被修改就会立即引发异常,而不是显示修改后的结果 这在多线程中容易出现这种错误; 使用foreach循环遍历集合 使用java1.5 foreach遍历集合更加快捷; 如下代码: public class TestForeach { public static void main(String[] args) {   //创建一个集合 Collection books = new HashSet(); books.add(new String("book1")); books.add(new String("book2")); books.add(new String("book3")); for (Object obj : books) {     String book = (String)obj;   System.out.println(book);   if (book.equals("book2"))   {     //下面代码会引发ConcurrentModificationException异常     books.remove(book);     }   } System.out.println(books); } } 注意foreach循环迭代访问集合元素时候,该集合也不能被改变否则会引发异常。 原因:foreach循环中的迭代变量不是集合元素本身,系统只是依次把集合元素赋值给 迭代变量,所以修改没有任何意义。

二 Set接口总结 Set集合不允许包含相同的集合元素,如果把相同的元素加到set集合添加操作将会失败 如下代码: public class TestSet { public static void main(String[] args) {   Set books = new HashSet();   //添加一个字符串对象   books.add(new String("Struts2"));   //再次添加一个字符串对象,   //因为两个字符串对象通过equals方法比较相等,所以添加失败,返回false boolean result = books.add(new String("Struts2"));   System.out.println(result);   //下面输出看到集合只有一个元素   System.out.println(books); } }
HashSet 类 HashSet 是Set接口的典型实现类,是按照hash算法来存储集合元素的具有很好的性能; 特点: 1 不能保证元素的排列顺序,顺序可能变化; 2 不是同步的,多线程访问是必须同步; 3 集合元素值可以是null; HashSet集合判断集合元素相等的标准是equals方法比较相等而且hashCode返回值也相等。 如果要把自己定义的某个类对象保存到HashCode中,需要重写equals()和hasnCode()方法, equals返回为true时hashCode值也应该相等。 HashSet有一个子类LinkedHashSet使用链表来维护元素的次序,这些元素是按照传入插入顺序来 保存的,由于要维护元素的循序性能比HashSet低但迭代性能好。
TreeSet类 TreeSet是SortedSet接口的唯一实现,可以保证元素处于排序状态。 几个额外的方法: Object first() 返回集合中的第一个元素; Object last() 返回集合中最后一个元素; Object lower(Object o)返回集合中位于指定元素之前的元素; Object higher(Object o)返回集合中位于指定元素之后的元素; SortedSet subSet(fromElement,toElement);返回此set的子集合从fromElement(包含) 到toElement(不包含); SortedSet tailSet(fromElement)返回此set的子集,大于等于fromElement; 看下面代码: public class TestTreeSet { public static void main(String[] args) {   TreeSet nums = new TreeSet();   //向TreeSet中添加四个Integer对象   nums.add(5);   nums.add(2);   nums.add(10);   nums.add(-9);   //输出集合元素,看到集合元素已经处于排序状态   System.out.println(nums);   //输出集合里的第一个元素   System.out.println(nums.first());   //输出集合里的最后一个元素   System.out.println(nums.last());   //返回小于4的子集,不包含4   System.out.println(nums.headSet(4));   //返回大于5的子集,如果Set中包含5,子集中还包含5   System.out.println(nums.tailSet(5));   //返回大于等于-3,小于4的子集。   System.out.println(nums.subSet(-3 , 4)); } } TreeSet会调用集合元素的compareTo(Object obj)方法比较元素之间的大小关系 将集合元素进行升序排序,这就自然排序。 如果要把自定义的类加入TreeSet集合里时候必须实现Comparable接口否则会引发异常, 集合里可以放一个没有实现Comparable接口的对象,但是取出时仍然会出异常。 可以定制排序规则可以在创建TreeeSet集合时候实现Comparator接口,实现里面的 int compare(T o1,T o2)方法。
三 List接口 List集合代表一个有序集合,每个元素都有对应的顺序索引,可以重复元素 可以通过索引来访问指定位置的集合元素。 List接口添加了根据索引来操作元素的方法: void add(int index,Object element)将元素element插入list集合的index处; void addAll(int index,Cllection c)将集合c所包含的元素全部插入List集合的index处; Object get(int index)返回集index处的元素。 int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。 参考jdk文档 下面程序示范了各个方法的用法 public class TestList { public static void main(String[] args) {   List books = new ArrayList();   //向books集合中添加三个元素   books.add(new String("J2EE企业应用实战"));   books.add(new String("Struts2权威指南"));   books.add(new String("基于J2EE的Ajax宝典"));   System.out.println(books);   //将新字符串对象插入在第二个位置   books.add(1 , new String("开发最佳实践"));   for (int i = 0 ; i < books.size() ; i++ )   {     System.out.println(books.get(i));   }   //删除第三个元素 books.remove(2);   System.out.println(books);   //判断指定元素在List集合中位置:输出1,表明位于第二位   System.out.println(books.indexOf(new String("开发最佳实践"))); //将第二个元素替换成新的字符串对象   books.set(1, new String("Struts2权威指南")); System.out.println(books); //将books集合的第二个元素(包括)到第三个元素(不包括)截取称子集合 System.out.println(books.subList(1 , 2));
} } List 接口专门添加了一个ListIterator接口专门来遍历List集合,增加了如下方法 boolean hasPrevious()返回迭代器关联的集合是否有上一个元素; Object previous()返回该迭代器的上一个元素; void add()在制定处添加一个元素; 示范程序: public class TestListIterator { public static void main(String[] args) {   String[] books = {     "book1",     "book2"   }; List bookList = new ArrayList(); for (int i = 0; i < books.length ; i++ )   {   bookList.add(books[i]);   }   ListIterator lit = bookList.listIterator();   while (lit.hasNext())   {   System.out.println(lit.next());   lit.add("-------分隔符-------"); }   System.out.println("==========下面开始反向迭代==========="); while(lit.hasPrevious()) {     System.out.println(lit.previous());   } } } ArrayList类和Vector类都是List实现类。ArrayList是线程不安全的 Vector是线程不安全的是个古老的类还有个子类Stack模拟栈的特性。

四 Queue 队列 Queue接口模拟了队列这种数据接口,具有先进先出的特点 有几个要注意的方法: Object element()获取队列头部元素但是不删除该元素; Object peek()获取队列头部元素但是不删除该元素,如果队列为空返回null; Object poll()获取队列的头部元素,并删除该元素; Object remove()获取队列的头部元素,并删除它; Queue 有连个实现类 LinkedList和PriorityQueue。
LinkedList是一个双向队列即实现了List接口又实现了Deque接口,而且可以 当做栈来使用。 下面代码示范了LinkedList集合的通用方法: public class TestLinkedList { public static void main(String[] args) {   LinkedList books = new LinkedList();   //将字符串元素加入队列的尾部   books.offer("BOOK1");   //将一个字符串元素入栈   books.push("BOOK2");   //将字符串元素添加到队列的头部   books.offerFirst("BOOK3");   for (int i = 0; i < books.size() ; i++ )   {     System.out.println(books.get(i));   }   //访问、并不删除队列的第一个元素   System.out.println(books.peekFirst());   //访问、并不删除队列的最后一个元素   System.out.println(books.peekLast());   //采用出栈的方式将第一个元素pop出队列   System.out.println(books.pop());   //下面输出将看到队列中第一个元素被删除   System.out.println(books);   //访问、并删除队列的最后一个元素   System.out.println(books.pollLast());   //下面输出将看到队列中只剩下中间一个元素   System.out.println(books);
} }


五 Map接口 Map用于保存具有映射关系的数据,因此Map集合保存了两组值,一个key一个是value, key和value是单向一对一关系即通过指定的key总能找到对应的唯一的value。key不允许重复。
HashMap和Hashtable 都是Map接口典型的实现类。 Hashtable是个古老的集合类是线程安全的,HashMap是线程不安全的所以性能要高点。 Hashtable不允许 null作为key和value但HashMap可以。 TreeMap对所有的key进行了排序和TreeSet一样有两种排序一个是自然排序二是指定排序 key实现Comparable接口。
六集合的工具类Collections 对List集合的排序操作方法 static void reverse(List list)反转List集合内元素的顺序。 static void shuffle(List list)对list集合进行随机排序。 static void sort(List list)根据元素的自然顺序进行升序排序。 static void sort(List list,Comparator c)指定Comparator产生的顺序对list进行排序。 static void swap(List list,int i,intj)将集合的i处元素和j出元素进行交换。 示范代码: public class TestSort { public static void main(String[] args) {   ArrayList nums = new ArrayList();   nums.add(2);   nums.add(-5);   nums.add(3);   nums.add(0);   //输出:[2, -5, 3, 0]   System.out.println(nums);   //将List集合元素的次序反转   Collections.reverse(nums);   //输出:[0, 3, -5, 2]   System.out.println(nums);   //将List集合元素的按自然顺序排序   Collections.sort(nums);   //输出:[-5, 0, 2, 3]   System.out.println(nums);   //将List集合元素的按随机顺序排序   Collections.shuffle(nums);   //每次输出的次序不固定   System.out.println(nums); } } 除了这些排序方法外还提供了查找替换操作。
最后总结下Collections类中提供的同步控制方法。 Collections 提供了多个像synchronizedXxx的方法,返回指定集合 对象的同步对象可以解决线程安全问题。 下面示例创建了四个同步集合对象 public class TestSynchronized { public static void main(String[] args) { //下面程序创建了四个同步的集合对象   Collection c = Collections.synchronizedCollection(new ArrayList());   List list = Collections.synchronizedList(new ArrayList()); Set s = Collections.synchronizedSet(new HashSet());   Map m = Collections.synchronizedMap(new HashMap()); } }

posted @ 2012-11-08 13:49  漫步云计算  阅读(170)  评论(0编辑  收藏  举报