黑马程序员——java基础---集合框架

 

一、集合框架

  概念集合框架是Java中为了方便对集合进行存储、操作而形成的体系。集合是针对对象最常见的一种存储形式。

  数组和集合类同是容器,区别在哪里?
     相同点
               集合和数组都是容器,都可一存储对象(对象引用)。
     不同点
               数组长度固定,集合长度可变。
               数组可以存储基本数据类型,集合却只能存储对象;

  集合类的特点集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

   集合框架常用类关系图:

  为什么会有这么多容器?

  答:因为每个容器对数据的存储方式都有所不同,这个存储方式就是常说的数据结构。

二、Collection接口  Collection 接口是集合框架中的顶层接口,所以其所有共性在其子接口中都可以得到体现。

  集合类中常用的方法:
      1、添加
       add(E e): 向集合中添加该元素。
            addAll(Collection<? extends E> c): 将指定集合中的所有元素都添加到此集合中。
      2、删除
        remove(Object o):从此集合中移除指定元素的单个实例,如果存在的话。
              removeAll(Collection<?> c):移除此集合中那些也包含在指定集合中的所有元素
            clear();清空集合中所有元素。
      3、判断
            contains(Object o): 判断集合中是否包含某个元素。
            containsAll(Collection<?> c):判断该集合是否包含另一集合中的所有元素。 
              isEmpty():判断集合是否为空。
      4、获取
                 iterator():返回在此集合的元素上进行迭代的迭代器。
                 size():获取集合长度。

     
5、取交集
             retainAll(Collection<?> c):保留本集合与另一集合的交集。  
      6、集合变数组
              toArray(T[] a) :返回包含此 collection 中所有元素的数组。

  注意:toArray(T[] a)返回数组的运行时类型与指定数组的运行时类型相同。此方法充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。如果指定的数组能容纳该 collection,则返回包含此 collection 元素的数组;否则,将分配一个具有指定数组的运行时类型和此 collection 大小的新数组;如果指定的数组能容纳 collection,并有剩余空间(即数组的元素比 collection 的元素多),那么会将数组中紧接 collection 尾部的元素设置为 null。所以数组长度与集合长度刚刚好最合适。
      因为Collection中有iterator()方法,所以每一个子类集合对象都具备迭代器。每个集合都具备取出的方式,而这个方式不足以用一个方法来描述,所以把取出动作封装成一个对象。因为数据结构不同,每个取出对象中取出的实现方式也不一样。取出的方式就通过类被描述。
     迭代器中的方法:
           next():返回迭代的下一个元素。
           hasNext():如果仍有元素可以迭代,则返回 true。
                 remove():从迭代器指向的 Collection 中移除迭代器返回的最后一个元素。
  注意
     1、迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration。迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException异常。迭代器的next方法返回值类型是Object,所以要记得类型转换。
     2、在迭代时循环中next调用一次,就要hasNext判断一次。next连续调用两次可能会发生NoSuchElementException异常。

三、List接口

  List接口是Collection的子接口。所以它在具备Collection共性的基础上,还有其自个儿的特性。它可以通过角标获取元素,也可以通过for循环获取元素。

    List特有方法

    1、添加
            add(int index,E element):在列表的指定位置插入指定元素。
                 addAll(int index, Collection<? extends E> c) :将指定 集合中的所有元素都插入到列表中的指定位置。
      2、删除
            remove(int index): 移除列表中指定位置的元素。
      3、修改
            set(int index, E element):用指定元素替换列表中指定位置的元素,返回以前在指定位置的元素。
  4、查找
             get(int index) :返回列表中指定位置的元素。
             subList(int fromIndex, int toIndex): 返回列表中指定的范围内的部分列表,含头不含尾。
             listIterator():返回此列表元素的列表迭代器。
                listIterator(int index):从列表的指定位置开始返回列表中元素的列表迭代器。

   ListIterator特有的方法
             add(E e):将指定的元素插入列表。
                previous():返回列表中的前一个元素。
                hasPrevious():如果逆向遍历列表,列表迭代器有多个元素,就返回 true。
                set(E e):用指定元素替换 next 或 previous 返回的最后一个元素。

四、Vector类和Enumeration接口

  Enumeration特有的方法

       hasMoreElements():测试此枚举是否包含更多的元素。
                nextElement():如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

  可见其性能相当于迭代器,只不过方法比较少。

  Vector特有方法:

       elements() :返回此向量的组件的枚举。 返回的类型是Enumernation类型的。

  所以对于Vector来说有以下取出元素方式:

    1、for循环
    2、迭代器
    3、列表迭代器
    4、get方法,遍历for循环

    5、枚举

五、linkedList类

  概念底层数据结构是链表,查询慢,增删快,线程不安全,效率高。

  特有的方法

          addFirst(E e):将指定元素插入此列表的开头。
                addLast(E e):将指定元素添加到此列表的结尾。
                getFirst():返回此列表的第一个元素。
                getLast():返回此列表的最后一个元素。
                removeFirst():移除并返回此列表的第一个元素。
                removeLast():移除并返回此列表的最后一个元素。
      注意:获取元素的这些方法。如果集合中没有元素,会出现 NoSuchElementException异常。
      JDK1.6出现的新特性:
                offerFirst(E e)
                offerLast(E e)
                peekFirst()
                peekLast()
                pollFirst()
                pollLast()
     
用法与上面方法一致,但获取元素时,如果集合中没有元素,则会返回 null 。

LinkedList模拟队列代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4 /*
 5  * 链表模队列,先进先出
 6  */
 7     public static void main(String[] args) {
 8         DuiLie dl = new DuiLie();
 9         dl.myAdd("aa");
10         dl.myAdd("bb");
11         dl.myAdd("cc");
12         dl.myAdd("dd");
13         
14         System.out.println(dl.myGet());
15     }
16 
17 }
18 
19 class DuiLie{
20     private LinkedList link;
21     
22     DuiLie(){
23         link = new LinkedList();
24     }
25     
26     public void myAdd(Object obj){
27         link.addFirst(obj);
28     }
29     
30     public Object myGet(){
31         return link.removeLast();
32     }
33     
34     public boolean isNull(){
35         return link.isEmpty();
36     }
37 }

 

六、ArrayList类

  概念:底层数据结构是数组,查询快,增删慢,线程不安全,效率高。是List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。

ArrayList去除重复对象代码:

 1 import java.util.ArrayList;
 2 import java.util.Iterator;
 3 
 4 public class ArrayListDemo {
 5 
 6     /**
 7      * 去除ArrayList的重复对象
 8      */
 9     public static void main(String[] args) {
10         ArrayList al = new ArrayList();
11         al.add("AA");
12         al.add("BB");
13         al.add("AA");
14         al.add("BB");
15         al.add("CC");
16         
17         System.out.println(getSingle(al));
18     }
19     public static ArrayList getSingle(ArrayList al){
20         ArrayList myAl = new ArrayList();
21         Iterator it = al.iterator();
22         while(it.hasNext()){
23             Object obj = it.next();
24             if(!myAl.contains(obj))
25                 myAl.add(obj);
26         }
27             return myAl;
28     }
29 }
30 /**
31  * 运行结果:[AA, BB, CC]
32  */

    上面比较的是字符串,所以可以成功。如果比较自定义对象时,那么就会失败。这是因为contains()方法底层是由equals()方法实现的,而Object类中的equals()方法比的是内存地址,所以我们如果相比较自定义对象,就需要复写equals()方法。

七、Set接口

  概念:一个不包含重复元素的 collection

     特点:

    1、无序(存入与取出的顺序不一致)

    2、唯一(存入集合的元素唯一)

八、HashSet类

  概念:不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用 null 元素。

遍历HashSet代码:

 1 public class HashSetDemo 
 2  2 {
 3  3     public static void main(String[] args)
 4  4     {
 5  5         HashSet<String> hs = new HashSet<String>();
 6  6         hs.add("AA");
 7  7         hs.add("BB");
 8  8         hs.add("CC");
 9  9         hs.add("BB");
10 10         
11 11         for (String s : hs) 
12 12         {
13 13             System.out.println(s);
14 14         }
15 15     }
16 16 }
17 /*
18  *运行结果:
19  * BB
20  * AA
21  * CC 
22  */

 

HashSet中存储自定义对象代码:

 1 import java.util.*;
 2 public class HashSetDemo
 3 {
 4     public static void sop(Object obj)
 5     {
 6         System.out.println(obj);
 7     }
 8     public static void main(String[] args)
 9     {
10         HashSet hs = new HashSet();
11         //向HashSet集合中添加元素
12         hs.add(new Person("a1",11));
13         hs.add(new Person("a2",12));
14         hs.add(new Person("a3",13));
15         hs.add(new Person("a2",12));
16         //对集合进行迭代
17         Iterator it = hs.iterator();
18         while(it.hasNext())
19         {
20             Person p = (Person)it.next();           
21            
22             sop(p.getName()+"::"+p.getAge());
23         }
24     }
25 }
26 //定义一个Person类
27 class Person
28 {
29     private String name;
30     private int age;
31     public String getName()
32     {
33         return name;
34     }
35     public int getAge()
36     {
37         return age;
38     }
39     Person(String name,int age)
40     {
41         this.name = name;
42         this.age = age;
43     }
44     //覆盖hashCode方法
45     public int hashCode()
46     {
47         return name.hashCode()+age*3;
48     }
49     //这里的equals是复写Object类里的equals方法
50     public boolean equals(Object obj)
51     {
52         if(!(obj instanceof Person))
53             return false;
54         Person p = (Person)obj;
55         return this.name.equals(p.name) && this.age == p.age;
56     }
57     
58 }

     判断元素唯一性的方式:通过对象的hashCode和equals方法来完成元素唯一性

    如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。

    如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。

    如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

九、TreeSet类

  概念使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

遍历TreeSet代码:

 1 public class TreSetDemo 
 2 {
 3     public static void main(String[] args)
 4     {
 5         TreeSet<Integer> ts = new TreeSet<Integer>();
 6             ts.add(22);
 7             ts.add(17);
 8             ts.add(24);
 9             ts.add(19);
10             ts.add(18);
11             ts.add(20);
12             ts.add(18);
13             ts.add(23);
14         
15         
16         for(Integer i : ts)
17         {
18             System.out.print(i+" ");
19         }
20     }
21 }            
22 //运行结果:17 18 19 20 22 23 24 

 TreeSet中对自定义对象进行排序:

 1 package filetools;
 2 
 3 import java.util.*;
 4 /**
 5  * 定义一个学生类,使可以按照姓名和年龄排序。
 6  *
 7  */
 8 public class TreeSetDemo
 9 {
10   public static void main(String[] args)
11   {
12       //定义一个TreeSet集合并添加元素
13       TreeSet ts = new TreeSet(new MyCompare());
14 
15       ts.add(new Student("sa01",22));
16       ts.add(new Student("sb01",21));
17       ts.add(new Student("sc09",20));
18       ts.add(new Student("sc09",19));
19       ts.add(new Student("sc06",18));
20       ts.add(new Student("sb06",18));
21       ts.add(new Student("sd07",29));
22       Iterator it = ts.iterator();
23       while(it.hasNext())
24       {
25           Student stu = (Student)it.next();
26           System.out.println(stu.getName()+"..."+stu.getAge());
27       }
28   }
29 }
30 //定义学生类
31 class Student implements Comparable
32 {
33   private String name;
34   private int age;
35 
36   public String getName()
37   {
38       return name;
39   }
40   public int getAge()
41   {
42       return age;
43   }
44   Student(String name,int age)
45   {
46       this.name = name;
47       this.age = age;
48   }
49   public int compareTo(Object obj)
50   {
51       if(!(obj instanceof Student))
52           throw new RuntimeException("不是学生对象");
53       Student s = (Student)obj;
54 
55       if(this.age>s.age)
56           return 1;
57       if(this.age==s.age)
58       {
59           return this.name.compareTo(s.name);
60       }
61       return -1;       
62   }
63   
64 }
65 
66 //定义一个比较器
67 class MyCompare implements Comparator
68 {
69   //覆盖compare方法
70   public int compare(Object o1,Object o2)
71   {
72       Student s1 = (Student)o1;
73       Student s2 = (Student)o2;
74 
75       int num = s1.getName().compareTo(s2.getName());
76       //当name相同时,再判断age
77       if(num==0)
78       {
79           return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));     
80       }       
81       return num;
82   }
83

十、Map接口

  Map存储键值对。同时要保证键的唯一性。当数据之间存在这映射关系时,就应该先想通过Map来实现。
  Map与Collection的区别
    1、Map存储的是键值对,是双列。Collection中是单列。
    2、Map存储元素使用put方法。Collection使用add方法。
    3、Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素。
    4、Map集合中键要保证键值唯一性。Collection中只有Set中有元素唯一性。

  常用方法
    1、添加
        put(K key, V value):返回这个键对应的原来的那个值。当存入一个新的键值时返回null,当存入一个已有键和不同的值时,新值会替换原来的值。返回原来的值
        putAll(Map<? extends K,? extends V> m): 从指定映射中将所有映射关系复制到此映射中。
       2、删除
        clear() :从此映射中移除所有映射关系。
        remove(Object key):如果存在一个键的映射关系,则将其从此映射中移除。 

    3、判断
        containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回true。 
        containsKey(Object key) :如果此映射包含指定键的映射关系,则返回true。
           isEmpty() :如果此映射未包含键-值映射关系,则返回true。

    4、获取
        get(Object key) :返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回null。
        size() :返回此映射中的键-值映射关系数。
        values() :返回此映射中包含的值的Collection视图

  因为Map中无迭代器,所以如果要遍历,需先转换成Set:
       keySet():返回此映射中包含的键的Set视图。
        entrySet():返回此映射中包含的映射关系的Set视图。 

十一、HashMap、TreeSet

  区别HashMap通过hashcode对其内容进行快速查找,排序不固定。而TreeMap中所有的元素都保持着某种固定的顺序。  

HashMap单键简单遍历:

 1 mport java.util.HashMap;
 2 import java.util.Map;
 3 import java.util.Set;
 4 
 5 public class HashMapTest {
 6 
 7     public static void main(String[] args) {
 8         Map<String, String> map = new HashMap<String, String>();
 9         map.put("001", "小明");
10         map.put("002", "小天");
11         map.put("003", "小强");
12 
13         //获取所有的键
14         Set<String> set = map.keySet();
15         for(String key : set)
16         {
17             String value = map.get(key);
18             System.out.println(key+":"+value);
19         }
20     }
21 
22 }

HashMap键-值遍历: 

 1 import java.util.HashMap;
 2 import java.util.Map;
 3 import java.util.Set;
 4 
 5 public class HashMapTest {
 6 
 7     public static void main(String[] args) {
 8         Map<String, String> map = new HashMap<String, String>();
 9         map.put("001", "小明");
10         map.put("002", "小天");
11         map.put("003", "小强");
12 
13         //获取所有的键
14         Set<Map.Entry<String,String>> set = map.entrySet();
15         for(Map.Entry<String,String> me : set)
16         {
17             String id = me.getKey();
18             String name = me.getValue();
19             System.out.println(id+":"+name);
20         }
21     }
22 
23 }

 

十二、Collections和Arrays类

  两者区别

    Collections:集合框架的工具类。里面定义的都是对集合操作的一系列静态方法。
    Arrays:数组的工具类。里面定义的都是对数组操作静态方法。
   Collection和Collections 有什么区别?
    Collection  是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口,List:对元素都有定义索引。有序的。可以含重复元素。Set:不含重复元素。无序。
    Collections 是集合框架中的一个工具类。该类中的方法都是静态的。提供的方法中有可以对list集合进行排序,二分查找等方法。通常常用的集合都是线程不安全的。因为要提高效率。如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。

  Collections常用方法
            fill(List<? super T> list, T obj):使用指定元素替换指定列表中的所有元素。

           max(Collection<? extends T> coll):根据元素的自然顺序,返回给定 collection 的最大元素。

           max(Collection<? extends T> coll, Comparator<? super T> comp):根据指定比较器产生的顺序,返回给定 collection 的最大元素。

           replaceAll(List<T> list, T oldVal, T newVal):使用另一个值替换列表中出现的所有某一指定值。

           reverse(List<?> list):反转指定列表中元素的顺序。

           reverseOrder():返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。

           reverseOrder(Comparator<T> cmp):返回一个比较器,它强行逆转指定比较器的顺序。

           shuffle(List<?> list):使用默认随机源对指定列表进行置换。

           sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。

           sort(List<T> list, Comparator<? super T> c):根据指定比较器产生的顺序对指定列表进行排序

           swap(List<?> list, int i, int j):在指定列表的指定位置处交换元素。 

           synchronizedCollection(Collection<T> c):返回指定 Collection 支持的同步(线程安全的) Collection。List Map Set 也都有返回支持同步的方法。
  Arrays常用方法
       asList(T... a) ;返回一个受指定数组支持的固定大小的列表。
         deepEquals(Object[] a1, Object[] a2): 如果两个指定数组彼此是深层相等 的,则返回true。
               sort(byte[] a):对指定byte型数组按数字升序进行排序。
            sort(byte[] a, int start, int end) :对指定byte型数组的指定范围按数字升序进行排序。
               binarySearch(byte[] a, byte key) :使用二分搜索法来搜索指定的byte型数组,以获得指定的值。 
               binarySearch(byte[] a,int start,int end,byte key) :使用二分搜索法来搜索指定的byte型数组的指定范围,以获得指定的值。

          toString(boolean[] a) :返回指定数组内容的字符串表示形式。 
      copyOfRange(byte[] bytes, int start, int end): 将指定数组的指定范围复制到一个新数组。 
      fill(boolean[] a, boolean val):将指定的 boolean 值分配给指定boolean型数组的每个元素。
      fill(boolean[] a, int start, int end, boolean val) :将指定的boolean值分配给指定boolean型数组指定范围中的每个元素。 
                        
  Arrays特殊方法
         asList(T... a):将数组变成list集合。
  这样做的好处就是可以使用集合的思想和方法来操作数组中的元素。将数组变成集合后,不可以使用集合的增删方法。因为数组的长度是固定的。如果增删。会发生 UnsupportedOperationException,变成集合后可以使用的方法有:        
            contains(Object o):如果列表包含指定的元素,则返回true。
            get(int index):返回列表中指定位置的元素。
               indexOf(Object o):返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回-1。 
               subList(int fromIndex, int toIndex):返回列表中指定的范围之间的部分视图,含头不含尾。 
  注意:        
      如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。
      如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。

           

 

posted @ 2015-07-16 01:26  shadowW_W  阅读(178)  评论(0编辑  收藏  举报