黑马程序员——集合类

一、集合类的由来

对象用于封装特有数据,对象多了需要存储;如果对象的个数不确定,就使用集合容器进行存储。

集合特点:
1. 用于存储对象的容器。
2. 集合的长度是可变的。
3. 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。

经典问题:数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。

数组中可以存储基本数据类型,集合只能存储对象。

集合框架的构成及分类如图所示

二、Collection接口

框架的顶层Collection接口:
Collection的常见方法:
1、添加:
boolean add(Object obj);
boolean addAll(Collection coll);

2、删除:
boolean remove(Object obj);
boolean removeAll(Collection coll);
void clear();
3、判断:
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty();判断集合中是否有元素

4、获取:
int size();
Iterator iterator();
取出元素的方式:迭代器。
该对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象是在容器中进行内部实现的,也就是iterator方法在每个容器中的实现方式是不同的。
对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口。

5、其他:
boolean retainAll(Collection coll);取交集
Object toArray();将集合转成数组

示例:

[java]  view plain copy
  1. import java.util.*;  
  2. public class CollectionDemo {  
  3.     public static void main(String[] args){  
  4.          Collection coll = new ArrayList();  
  5.          show(coll);  
  6.          System.out.println( "---------------------------------" );  
  7.          Collection c1 = new ArrayList();  
  8.          Collection c2 = new ArrayList();  
  9.          show(c1,c2);  
  10.     }  
  11.           
  12.     public static void show(Collection coll){  
  13.     //1、添加元素,add  
  14.         coll.add( "abc1");  
  15.         coll.add( "abc2");  
  16.         coll.add( "abc3");  
  17.         System.out.println( "coll:" + coll);  
  18.          //2、删除元素,remove  
  19.         coll.remove( "abc2");//会改变集合的长度  
  20.         System.out.println( "coll:" + coll);  
  21.         //清空集合  
  22.         //coll.clear();  
  23.         System.out.println(coll.contains( "abc1"));  
  24.     }  
  25.     public static void show(Collection c1,Collection c2){  
  26.         //给c1添加元素  
  27.         c1.add( "abc1");  
  28.         c1.add( "abc2");  
  29.         c1.add( "abc3");  
  30.         c1.add( "abc4");  
  31.         //给c2添加元素  
  32.         c2.add( "abc2");  
  33.         c2.add( "abc6");  
  34.         c2.add( "abc7");  
  35.         System.out.println( "c1:" + c1);  
  36.         System.out.println( "c2:" + c2);  
  37.         //演示addAll  
  38.         //将c2中的元素添加到c1中  
  39.         c1.addAll(c2);  
  40.         //演示removeAll  
  41.         //从c1集合中删除与c2集合相同的元素  
  42.         boolean b = c1.removeAll(c2);  
  43.         System.out.println( "removeAll:" + b);  
  44.         //演示containsAll  
  45.         boolean b1 = c1.containsAll(c2);  
  46.         System.out.println( "containsAll:" + b1);  
  47.             //演示retainAll  
  48.             //取交集,保留和指定的集合相同的元素  
  49.         boolean b2 = c1.retainAll(c2);  
  50.         System.out.println( "c1、c2交集:" + c1);  
  51.     }  
  52. }  
程序运行结果如图:

示例2:

[java]  view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.Collection;  
  3. import java.util.Iterator;  
  4.  public class IteratorDemo{  
  5.      public static void main(String[] args){  
  6.          Collection coll = new ArrayList();  
  7.          coll.add( "abc1");  
  8.          coll.add( "abc2");  
  9.          coll.add( "abc3");  
  10.          coll.add( "abc4");  
  11.          System.out.println(coll);  
  12. /*使用了Collection中的iterator()方法。调用集合中的迭代器方法,是为了获取集合中 
  13. 的迭代器对象。*/  
  14.          Iterator it1 = coll.iterator();  
  15.          while(it1.hasNext()){  
  16.              System.out.println(it1.next());  
  17.          }  
  18.  //for循环结束,Iterator变量内存释放,更高效  
  19.          for(Iterator it2 = coll.iterator();it2.hasNext();){  
  20.              System.out.println(it2.next());  
  21.          }  
  22.      }  
  23.  }  
程序运行结果如图:


三、List、Set

Collection
|--List:有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素。
|--Set:元素不能重复,无序。
List:特有的常见方法。
有一个共性特点就是都可以操作角标。
1、添加
void add(index,element);
void addAll(index,collection);
2、删除
Object remove(index);
3、修改
Object set(index,element);
4、获取:
Object get(index);
int indexOf(object);
int lastIndexOf(object);
List subList(from,to);
List集合可以完成对元素的增删改查。

示例:

[java]  view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3. public class ListDemo{  
  4.     public static void main(String[] args){  
  5.         List list = new ArrayList();  
  6.         show(list);  
  7.     }  
  8.     public static void show(List list){  
  9.         //添加元素  
  10.         list.add( "abc1" );  
  11.         list.add( "abc2" );  
  12.         list.add( "abc3" );  
  13.         System.out.println(list);  
  14.  //插入元素  
  15.         list.add(1"abc2" );  
  16.  //删除元素  
  17.         System.out.println( "remove:" + list.remove(2));  
  18.  //修改元素  
  19.         System.out.println( "set:" + list.set(1,"abc8" ));  
  20. //获取元素:  
  21.         System.out.println( "get:" + list.get(0));  
  22.  //获取子列表  
  23.         System.out.println( "sublist:" + list.subList(1,2));  
  24.         System.out.println(list);  
  25.     }  
  26. }  
程序结果如图所示:

示例2:

[java]  view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.Iterator;  
  3. import java.util.List;  
  4. import java.util.ListIterator;  
  5. public class ListDemo{  
  6.     public static void main(String[] args){  
  7.         List list = new ArrayList();  
  8.         show(list);  
  9.     }  
  10.     public static void show(List list){  
  11.         list.add( "abc1");  
  12.         list.add( "abc2");  
  13.         list.add( "abc3");  
  14.         list.add( "abc4");  
  15.         Iterator it = list.iterator();  
  16.         while(it.hasNext()){  
  17.             System.out.println( "next:" + it.next());  
  18.         }  
  19.  //list特有的取出元素的方式之一  
  20.         for(int x = 0; x < list.size(); x++){  
  21.             System.out.println( "get:" + list.get(x));  
  22.         }  
  23.     }  
  24.  }  
程序运行结果如图所示:

示例3:

[java]  view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.Iterator;  
  3. import java.util.List;  
  4. public class ListDemo{  
  5.     public static void main(String[] args){  
  6.         List list = new ArrayList();  
  7.         list.add( "abc1");  
  8.         list.add( "abc2");  
  9.         list.add( "abc3");  
  10.         System.out.println( "list:" + list);  
  11.         Iterator it = list.iterator();  
  12.         while(it.hasNext()){  
  13.             Object obj = it.next();  
  14.             if(obj.equals("abc2" )){  
  15.                 list.add( "abc9");  
  16.             } else{  
  17.                 System.out.println( "next:" + obj);  
  18.             }  
  19.             System.out.println(list);  
  20.         }  
  21.     }  
  22. }  
程序运行结果如图所示:

在迭代器过程中,不要使用集合操作元素,容易出现异常:java.util.ConcurrentModificationException。
可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。

[java]  view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3. import java.util.ListIterator;  
  4.  public class ListDemo{  
  5.      public static void main(String[] args){  
  6.          List list = new ArrayList();  
  7.          list.add( "abc1");  
  8.          list.add( "abc2");  
  9.          list.add( "abc3");  
  10.          System.out.println( "list:" + list);  
  11.          ListIterator it = list.listIterator(); //获取列表迭代器对象  
  12. //它可以实现在迭代过程中完成对元素的增删改查。  
  13. //注意:只有list集合具备该迭代功能。  
  14.          while(it.hasNext()){  
  15.              Object obj = it.next();  
  16.              if(obj.equals("abc3" )){  
  17.                  it.add( "abc9");  
  18.              }  
  19.          }  
  20.          System.out.println( "hasNext:" + it.hasNext());  
  21.          System.out.println( "hasPrevious:" + it.hasPrevious());  
  22.          while(it.hasPrevious()){  
  23.              System.out.println( "previous:" + it.previous());  
  24.          }  
  25.          System.out.println( "list:" + list);  
  26.      }  
  27. }  

程序运行结果如图:


四、Vector、ArrayList、LinkedList

List:
|--Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
|--ArrayList:内部是数组数据结构,是不同步的,替代了Vector。替代了Vector,查询的速度快。
|--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
LinkedList方法:
addFirst();
addLast();
jdk1.6版本后新方法:
offerFirst();与addFirst方法没有区别。
offerLast();与addLast方法没有区别。
---------------------------------------------------------
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException。
getLast();
jdk1.6版本后新方法:
peekFirst();//获取但不移除,如果链表为空,返回null。
peekLast();
--------------------------------------------------------
removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException。
removeLast();

jdk1.6版本后新方法:
pollFirst();//获取并移除,如果链表为空,返回null;
pollLast();

示例:

[java]  view plain copy
  1. import java.util.Iterator;  
  2. import java.util.LinkedList;  
  3.   
  4.  public class LinkedListDemo{  
  5.      public static void main(String[] args){  
  6.          LinkedList link = new LinkedList();  
  7.   
  8.          link.addFirst( "abc1");  
  9.          link.addFirst( "abc2");  
  10.          link.addFirst( "abc3");  
  11.          link.addFirst( "abc4");  
  12.   
  13.          Iterator it = link.iterator();  
  14.          while(it.hasNext()){  
  15.              System.out.println( "next:" + it.next());  
  16.          }  
  17.   
  18.          System.out.println(link);  
  19.          System.out.println("getFirst:" + link.getFirst()); //获取第一个,但是不删除。  
  20.          System.out.println("getLast:" + link.getLast());  
  21.          System.out.println("removeFirst:" + link.removeFirst()); //获取第一个,但是删除  
  22.          System.out.println("removeLast:" + link.removeLast());  
  23. //删除所有元素的方法  
  24.          while(!link.isEmpty()){  
  25.              System.out.println(link.removeFirst());  
  26.          }  
  27.      }  
  28. }  
程序运行结果如图:


五、Set

Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
|--HashSet:内部数据结构是哈希表,是不同步的。
|--TreeSet:可以对Set集合中的元素进行排序,是不同步的。

示例:

[java]  view plain copy
  1. import java.util.HashSet;  
  2. import java.util.Iterator;  
  3. import java.util.Set;  
  4. public class HashSetDemo{  
  5.     public static void main(String[] args){  
  6.         Set hs = new HashSet();  
  7.         hs.add( "hashhaha");  
  8.         hs.add( "hashheihei");  
  9.         hs.add( "hashhehe");  
  10.         hs.add( "hashxixi");  
  11.     Iterator it = hs.iterator();  
  12.     while(it.hasNext()){  
  13.         System.out.println(it.next());  
  14.         }  
  15.     }  
  16. }  
程序运行结果如图:

哈希表确定元素是否相同
1. 判断的是两个元素的哈希值是否相同。如果相同,再判断两个对象的内容是否相同。
2. 判断哈希值相同,其实判断的是对象的HashCode方法。判断内容相同,用的是equals方法。
PS:
如果哈希值不同,不需要判断equals。往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人,视为相同元素。

[java]  view plain copy
  1. import java.util.HashSet;  
  2. import java.util.List;  
  3. import java.util.Iterator;  
  4. public class HashSetTest{  
  5.     public static void main(String[] args){  
  6.     HashSet hs = new HashSet();  
  7.     hs.add( new Person("lisi4" ,24));  
  8.     hs.add( new Person("lisi7" ,27));  
  9.     hs.add( new Person("lisi1" ,21));  
  10.     hs.add( new Person("lisi9" ,29));  
  11.     hs.add( new Person("lisi7" ,27));  
  12.     Iterator it = hs.iterator();  
  13.     while(it.hasNext()){  
  14.         Person p = (Person)it.next();  
  15.         System.out.println(p.getName() + "..." + p.getAge());  
  16.         }  
  17.     }  
  18. }  
  19. class Person{  
  20.      private String name;  
  21.      private int age;  
  22.      public Person(){  
  23.      }  
  24.      public Person(String name,int age){  
  25.          this.name = name;  
  26.          this.age = age;  
  27.      }  
  28.      public void setName(String name){  
  29.          this.name = name;  
  30.      }  
  31.      public String getName(){  
  32.          return this .name;  
  33.      }  
  34.      public void setAge(int age){  
  35.          this.age = age;  
  36.      }  
  37.      public int getAge(){  
  38.          return this .age;  
  39.      }  
  40.      public int hashCode(){  
  41.          return name.hashCode() + age * 39;  
  42.      }  
  43.      public boolean equals(Object obj){  
  44.          if(this == obj)  
  45.              return true ;//同一个对象放两次,直接返回true  
  46.          if(!(obj instanceof Person))  
  47.              throw new ClassCastException("类型错误");  
  48.          Person p = (Person)obj;  
  49.          return this .name.equals(p.name) && this.age == p.age;  
  50.      }  
  51. }  
程序运行结果为:

定义功能去除ArrayList中的重复元素

示例:

[java]  view plain copy
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3. import java.util.ListIterator;  
  4. public class ArrayListTest {  
  5.     public static void main(String[] args) {  
  6.         List<String> list = new ArrayList<String>();  
  7.         list.add("a");  
  8.         list.add("a");  
  9.         list.add("b");  
  10.         list.add("b");  
  11.         list.add("c");  
  12.         list.add("c");  
  13.         List<String> li = getSingleElement(list);  
  14.         System.out.println(li);  
  15.     }  
  16.   
  17.     public static List<String> getSingleElement(List<String> list) {  
  18.         ArrayList<String> temp = new ArrayList<String>();  
  19.         ListIterator<String> it = list.listIterator();  
  20.         while(it.hasNext()){  
  21.             String str = it.next();  
  22.             if(!temp.contains(str))  
  23.                 temp.add(str);  
  24.         }  
  25.         return temp;  
  26.     }  
  27. }  
程序运行结果如图:

TreeSet对元素进行排序的方式一: 让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式:让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。将该类对象作为参数传递给TreeSet集合的构造函数。

PS:

如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器的比较规则为准。
TreeSet集合的底层是二叉树进行排序的。

示例:对字符串进行长度排序

[java]  view plain copy
  1. import java.util.Comparator;  
  2. import java.util.Iterator;  
  3. import java.util.TreeSet;  
  4.     public class TreeSetTest{  
  5.         public static void main(String[] args){  
  6.             TreeSet ts = new TreeSet(new ComparatorByLen());  
  7.             ts.add( "aaaa");  
  8.             ts.add( "zz");  
  9.             ts.add( "nbag");  
  10.             ts.add( "cba");  
  11.             ts.add( "abc");  
  12.             Iterator it = ts.iterator();  
  13.             while(it.hasNext()){  
  14.                 System.out.println(it.next());  
  15.             }  
  16.         }  
  17. }  
  18.     class ComparatorByLen implements Comparator{  
  19.         public int compare(Object o1,Object o2){  
  20.             String s1 = (String)o1;  
  21.             String s2 = (String)o2;  
  22.             int temp = s1.length() - s2.length();  
  23.             return temp == 0?s1.compareTo(s2):temp;  
  24.         }  
  25.      }  
程序运行结果为:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值