码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员——Java基础---集合(一)---Collection、set、list

时间:2015-08-09 22:28:12      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ------

                            集合框架

java中有许多的集合,也称为容器,下图便是集合框架的构成及分类。

技术分享

 

一、为什么出现集合类?

        面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

二、数组和集合类同是容器,有何不同?

        数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。

三、集合类的特点

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

 

                   Collection

        Collection是集合框架中的常用接口。其下有两个子接口:List(列表),Set(集)。

       所属关系:

            Collection

                     |--List//元素是有序的,元素可以重复。因为该集合体系有索引。

                     |--Set//元素是无序的,元素不可以重复。

   以下是Collection的总述:

  1 import java.util.*;
  2 /*
  3 Collection定义了集合框架的共性功能。
  4 
  5 1    添加
  6         add(e);      
  7         addAll(collention);
  8 2    删除
  9         remove(e)
 10         removeAll(collection);
 11         clear();
 12 3    判断
 13         contains(e)
 14         isEmpty();
 15 4    获取
 16         iterator()  迭代器iterator()
 17         size();
 18 5    获取交集
 19         retainAll()
 20 6    集合变数组
 21         toArray()
 22 
 23 1    add方法的参数类型是Object。以便于接收任意类型对象
 24 2    集合中存储的都是对象的引用(地址)
 25 
 26 迭代器
 27 
 28     什么是迭代器呢?
 29     其实就是集合的取出元素的方式
 30     如同抓娃娃游戏机中的夹子
 31 
 32     迭代器是去除方式,会直接访问集合中的元素
 33     所以将迭代器通过内部类的形式来进行描述
 34     通过容器的Iterator()方法获取该内部类的对象
 35     2、迭代注意事项
 36 
 37         迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。
 38         迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。
 39         迭代器的next方法返回值类型是Object,所以要记得类型转换。
 40 
 41 */
 42 class CollectionDemo
 43 {
 44     public static void main(String[] args)
 45     {
 46         method_get();
 47     } 
 48     public static void sop(Object obj)//打印一切对象
 49     {
 50         System.out.println(obj);
 51     }
 52     
 53     public static void base_method()
 54     {
 55         //创建一个集合容器。使用Collection接口的子类。ArrayList
 56         ArrayList al = new ArrayList();
 57 
 58         //1,添加元素。
 59         al.add("java01");//add(Object obj);
 60         al.add("java02");
 61         al.add("java03");
 62         al.add("java04");
 63 
 64         //打印原集合。
 65         sop("原集合:"+al);
 66 
 67 
 68         //3,删除元素。
 69         //al.remove("java02");
 70         //al.clear();//清空集合。
 71 
 72 
 73         //4,判断元素。
 74         sop("java03是否存在:"+al.contains("java03"));
 75         sop("集合是否为空?"+al.isEmpty());
 76 
 77 
 78         //2,获取个数。集合长度。
 79         sop("size:"+al.size());
 80 
 81         //打印改变后的集合。
 82         sop(al);
 83 
 84     }
 85 
 86     public static void method_get()
 87     {
 88         ArrayList a1=new ArrayList();//创建一个列表集合
 89         a1.add("java01");//添加元素
 90         al.add("java02");
 91         al.add("java03");
 92         al.add("java04");
 93         /*
 94         Iterator it=a1.iterator();//获取迭代器,用于取出集合中的元素
 95         while(it.hasNext()) 第一种打印方式:
 96         {
 97             sop(it.next());
 98         }
 99         */
100         //第二种打印方式:,相对于第一种节省了开辟it的资源。
101         for(Iterator it=a1.iterator();it.hasNext();)
102         {
103             sop(it.next());//在迭代时循环中next调用一次,就要hasNext判断一次。
104         }
105     }
106     public static void method_2()
107     {
108         ArrayList a11=new ArrayList();//创建集合对象
109         a11.add("java01");
110         al1.add("java02");
111         al1.add("java03");
112         al1.add("java04");
113         ArrayList al2 = new ArrayList();//创建集合对象
114 
115         al2.add("java03");
116         al2.add("java04");
117         al2.add("java05");
118         al2.add("java06");
119 
120         a11.retainAll(a12);//取交集,保留在a11中
121         sop("a11:"+a11);
122         
123         
124         a11.IndexOf(2,"java110");//在 a11集合中 用java110替代 位置2 上的元素
125         sop("a11:"+a11);
126     }
127 }

                            List

一、List

组成

        List:元素是有序的,元素可以重复。因为该集合体系有索引。

            |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

            |--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。

            |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。

 

二、List的特有方法

        凡是可以操作角标的方法都是该体系特有的方法。

1、增

        booleanadd(index,element);//指定位置添加元素

        BooleanaddAll(index,Collection);//在指定位置增加给定集合中的所有元素,若省略位置参数,则在当前集合的后面依次添加元素

2、删

        Booleanremove(index);//删除指定位置的元素

3、改

        set(index,element);//修改指定位置的元素。

4、查

        get(index);//通过角标获取元素

        subList(from,to);//获取部分对象元素

5、其他

        listIterator();//List特有的迭代器

        indexOf(obj);//获取元素第一次出现的位置,如果没有则返回-1

注:List集合判断元素是否相同,移除等操作,依据的是元素的equals方法。

 

三、ListIterator

1、概述 

        ListIterator是List集合特有的迭代器,是Iterator的子接口。

       在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。

2、ListIterator特有的方法

        add(obj);//增加

        set(obj);//修改为obj

        hasPrevious();//判断前面有没有元素

        previous();//取前一个元素

 

四、枚举Enumeration

枚举:

        就是Vector特有的取出方式。Vector有三种取出方式。

        其实枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。

特有方法:

         addElement(obj);//添加元素,相当于add(obj);

         Enumerationelements();//Vector特有取出方式(枚举)

         hasMoreElements();//相当于Iterator的hasNext()方法

         nextElements();//相当于Iterator的next()方法

例:  

 1 import java.util.*;
 2 /*
 3 枚举就是Vector特有的取出方式。
 4 发现枚举和迭代器很像。
 5 其实枚举和迭代是一样的。
 6 因为枚举的名称以及方法的名称都过长。
 7 所以被迭代器取代了。
 8 枚举郁郁而终了。
 9 */
10 class VectorDemo 
11 {
12     public static void main(String[] args) 
13     {
14         Vector v = new Vector();//创建容器
15 
16         v.add("java01");//添加元素
17         v.add("java02");
18         v.add("java03");
19         v.add("java04");
20 
21         Enumeration en = v.elements();//枚举
22 
23         while(en.hasMoreElements())//遍历,只要存在元素
24         {
25             System.out.println(en.nextElement());
26         }
27     }
28 }

五、LinkedList

 1 import java.util.*;
 2 /*
 3  LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
 4 LinkedList:特有方法
 5 addFirst();
 6 addLast();
 7 
 8 removeFirst();获取删除,当空时,出现异常
 9 removeLast();
10 
11 getFirst();获取不删除
12 getLast();
13 
14 offerFirst();
15 offerLast();
16 
17 peekFirst();
18 peekLast();
19 
20 pollFirst();
21 pollLast();
22 
23 
24 */
25 /*
26 使用LinkedList模拟一个堆栈或者队列数据结构
27 
28 堆栈:先进后出  如同一个杯子
29 队列:先进先出First in First out FIFO  如同一个水管
30 */
31 import java.util.*;
32 class DuiLie
33 {
34     private LinkedList link;//将队列私有化
35     DuiLie()               //创建新的队列
36     {
37         link=new LinkedList();
38     }
39     public void myAdd(Object obj)//增加新元素
40     {
41         link.addFirst(obj);
42     }
43     public Object myGet()   //获得元素,先进后出 堆栈
44     {
45         return link.removeFirst();
46     }
47     public Object myGet2()//获得元素  先进先出   队列
48     {
49         return link.removeLast();
50     }
51     public boolean isNull()  //判断是否为空
52     {
53         return link.isEmpty();
54     }
55 }
56 class LinkedListTest
57 {
58     public static void sop(Object obj)
59     {
60         System.out.println(obj);
61     }
62     public static void main(String[] args)
63     {
64         DuiLie d1=new DuiLie();
65         d1.myAdd("java01");
66         d1.myAdd("java02");
67         d1.myAdd("java03");
68         d1.myAdd("java04");
69         while(!d1.isNull())
70         {
71             System.out.println(d1.myGet());//先进后出 堆栈
72             System.out.println(d1.myGet2());//先进先出   队列
73         }
74         sop(d1);
75     }
76 }

   Set

一、概述

        Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。     

           |--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。

           |--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。

        Set集合的功能和Collection是一致的。

二、HasSet

        HashSet:线程不安全,存取速度快。

       可以通过元素的两个方法,hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。

注意:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。

示例:

 1 /*
 2 往hashSet集合中存入自定对象
 3 姓名和年龄相同为同一个人,重复元素。
 4 思路:1、对人描述,将人的一些属性等封装进对象 
 5       2、定义一个HashSet容器,存储人对象 
 6       3、取出 
 7 */
 8 import java.util.*;
 9 class HashSetTest 
10 {
11     public static void sop(Object obj)//打印任何对象
12     {
13         System.out.println(obj);
14     }    
15     public static void main(String[] args) 
16     {
17         HashSet hs = new HashSet();//建立集合
18         hs.add(new Person("a1",11));//存储元素
19         hs.add(new Person("a2",12));
20         hs.add(new Person("a3",13));
21         //hs.add(new Person("a2",12));
22         //hs.add(new Person("a4",14));
23         //sop("a1:"+hs.contains(new Person("a2",12)));
24         //hs.remove(new Person("a4",13));
25         Iterator it = hs.iterator();//调用集合 共有的 迭代器
26 
27         while(it.hasNext())//遍历集合,
28         {
29             Person p = (Person)it.next();
30             sop(p.getName()+"::"+p.getAge());
31         }
32     }
33 }
34 class Person//创建人对象,并对其进行描述
35 {
36     private String name;
37     private int age;
38     Person(String name,int age)
39     {
40         this.name = name;
41         this.age = age;
42     }
43     public int hashCode()//自定义 哈希值
44     {
45         System.out.println(this.name+"....hashCode");
46         return name.hashCode()+age*37;
47     }
48 
49     public boolean equals(Object obj)//复写equals方法,定义自己的比较方式
50     {
51         if(!(obj instanceof Person))//先确定调用的obj是不是  人类
52         return false;
53 
54         Person p = (Person)obj;//向下转型,使obj的身份变为person
55         System.out.println(this.name+"...equals.."+p.name);
56         return this.name.equals(p.name) && this.age == p.age;//先比较姓名再比较年龄
57     }
58 
59     
60     public String getName()//返回姓名
61     {
62         return name;
63     }
64     public int getAge()//返回年龄
65     {
66         return age;
67     }
68 }

三、TreeSet

1、特点

        a、底层的数据结构为二叉树结构(红黑树结构)

        b)可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。

        java中的很多类都具备比较性,其实就是实现了Comparable接口。

注意:排序时,当主要条件相同时,按次要条件排序。

   1)第一种排序方式:自然排序

        让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。

示例:

 

 1 /*
 2 TreeSet 排序的第一种方式,让元素自身具备比较性
 3 元素需要实现Comparable接口,覆盖compareTo方法
 4 这种方式也称为元素的自然顺序,或者叫做默认顺序
 5 */
 6 import java.util.*;
 7 class TreeSetDemo
 8 {
 9     public static void main(String[] args)
10     {
11         TreeSet ts=new TreeSet();//建立二叉树集合对象
12         ts.add(new Student("lisi02",22));//添加元素进集合
13         ts.add(new Student("lisi007",20));
14         ts.add(new Student("lisi09",19));
15         ts.add(new Student("lisi08",19));
16         ts.add(new Student("lisi007",20));
17         ts.add(new Student("lisi01",40));
18 
19         Iterator it = ts.iterator();//调用集合中的迭代器
20         while(it.hasNext())//遍历 容器成员
21         {
22             Student stu = (Student)it.next();
23             System.out.println(stu.getName()+"..."+stu.getAge());
24         }
25     }
26 }
27 class Student    implements Comparable//该接口赋予了学生具备比较性
28 {
29     private String name;
30     private int age;
31     Student(String name,int age)
32     {
33         this.name=name;
34         this.age=age;
35     }
36     public int compareTo(Object obj)//复写compareTo方法
37     {
38         if(!(obj instanceof Student))//判断obj是否为学生对象
39         throw new RuntimeException("不是学生对象");
40         Student s=(Student)obj;//向下转型
41         System.out.println(this.name+".....compareto..."+s.name);
42         if(this.age>s.age)
43             return 1;
44         if(this.age==s.age)//如果年龄相等,便运用字符串的比较方式
45         {
46             return this.name.compareTo(s.name);
47         }
48         return -1;
49     }
50     public String getName()//获取姓名方法
51     {
52         return name;
53     }
54     public int getAge()//返回年龄
55     {
56         return age;
57     }
58 }

  2)第二种方式:比较器

 1 import java.util.*;
 2 /*
 3 当元素自身不具备比较性,或者具备的比较性不是所需要的
 4 这时需要让容器自身具备比较性
 5 定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
 6 
 7 当两种排序都存在时,以比较器为主
 8 
 9 定义一个类,实现Comparator接口,覆盖compare方法
10 
11 */
12 class TreeSetDemo2 
13 {
14     public static void main(String[] args) 
15     {
16         TreeSet ts = new TreeSet();
17 
18         ts.add(new Student("lisi02",22));
19         ts.add(new Student("lisi02",21));
20         ts.add(new Student("lisi007",20));
21         ts.add(new Student("lisi09",19));
22         ts.add(new Student("lisi06",18));
23         ts.add(new Student("lisi06",18));
24         ts.add(new Student("lisi007",29));
25         //ts.add(new Student("lisi007",20));
26         //ts.add(new Student("lisi01",40));
27 
28         Iterator it = ts.iterator();//调用集合中的迭代器,用于遍历
29         while(it.hasNext())//遍历集合,每次调用it.next,都要判断该语句
30         {
31             Student stu = (Student)it.next();
32             System.out.println(stu.getName()+"..."+stu.getAge());
33         }
34     }
35 }
36 class Student implements Comparable//该接口让学生具备比较性
37 {
38     private String name;
39     private int age;
40     Student(String name,int age)
41     {
42         this.name=name;
43         this.age=age;
44     }
45     public String getName()
46     {
47         return name;
48     }
49     public int getAge()
50     {
51         return age;
52     }
53     public int compareTo(Object obj)//复写compareTo方法,定义自己的比较方式
54     {
55         if(!(obj instanceof Student))
56             throw new RuntimeException("不是学生对象");
57         Student s=(Student)obj;
58         if(this.age>s.age)
59             return 1;
60         if(this.age==s.age)
61         {
62             return this.name.compareTo(s.name);
63         }
64         return -1;
65     }
66 }
67 
68 class MyCompare implements Comparator//创建比较器,实现Comparator接口
69 {
70     public int compare(Object o1,Object o2)
71     {
72         Student s1=(Student)o1;
73         Student s2=(Student)o2;
74         int num = s1.getName().compareTo(s2.getName());//比较姓名
75         if(num==0)
76         {
77             return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));//后比较年龄
78         }
79         return num;
80     }
81 
82 }
83 class StrLenComparator implements Comparator//创建长度比较器,实现Comparator接口
84 {
85     public int compare(Object obj1,Object obj2)
86     {
87         String s1=(String)obj1;
88         String s2=(String)obj2;
89         if(s1.length()>s2.length())//比较长度
90             return 1;
91         if(s1.length()>s2.length())
92         {
93             return s1.compareTo(s2);
94         }
95         return -1;
96     }
97 }

 自我总结:

    List接口有三个实现类:LinkedList,ArrayList,Vector

      LinkedList:底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储下一个元素的地址。链表增删快,查找慢

      ArrayList和Vector的区别:ArrayList是非线程安全的,效率高;Vector是基于线程安全的,效率低 
        List是用来处理序列的,而set是用来处理集的。 

 

黑马程序员——Java基础---集合(一)---Collection、set、list

标签:

原文地址:http://www.cnblogs.com/ktlshy/p/4716377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!