zoukankan      html  css  js  c++  java
  • 黑马程序员——Java基础---集合(一)---Collection、set、list

    ------<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是用来处理集的。 

  • 相关阅读:
    ruby 中super和super()的区别
    SeleniumWebdriver系列教程(2)————浏览器的简单操作
    ruby设计模式之合成模式1————基本的合成模式
    ruby中::究竟代表什么?
    手工测试用例就是自动化测试脚本——使用ruby 1.9新特性进行自动化脚本的编写
    如何使用bluecloth
    如何使用ruby去实例化1个autoit对象
    Ruby设计模式之策略模式二————更ruby些的策略模式
    SeleniumWebdriver系列教程(1)————快速开始
    Seleniumwebdriver系列教程(3)————如何执行一段js脚本
  • 原文地址:https://www.cnblogs.com/ktlshy/p/4716377.html
Copyright © 2011-2022 走看看