集合与数组详解

一、数组与集合的基础介绍:

  1.数组

    (1)同一组数据类型的集合,其实数组就是一个容器

    (2)数组的好处在于可以对内部元素从0开始进行索引编号,方便对内部元素进行操作。

    (3)数组的声明

        int[ ] name=new int[ X ];

        int为声明数组所存储的元素类型,name为声明数组的名称,x为数组所包含具体几个元素;

        另外还可以用以下方式声明数组:

        int[ ]  name=new int[ ]{元素1,元素2 };

        int[ ]  name={ 元素1,元素2 };

        这样声明数组还将数组内具体元素都进行了表示。   

    (4)数组的具体操作

                   数组最常用的操作就是通过索引取元素

        name[ index ],name为数组名称,index为索引,要牢记数组是固定长度固定类型的容器。

  2.集合

    (1)集合存放于java.util包中,集合类中存放的都是对象的引用并没有存放具体的对象内容,我们称集合中的对象就是指对象的引用 集合中主要包含三类接口,Set(集)、List(列表)、Map(映射)

      Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是Set和List。Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。

      Map是Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。Map包含了key-value对。Map不能包含重复的key,但是可以包含相同的value。

      Iterator,所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法:

        <1>hasNext()是否还有下一个元素。

        <2>next()返回下一个元素。

        <3>remove()删除当前元素。

          Iterator遍历数组举例

            ArrayList al  = new ArrayList();

            Iterator iter= al.iterator();

            while(iter.hasNext()){

                      System.out.println(iter.next());
                                      }

     (2)下图详细介绍了集合类的接口,及接口实现类集合的特点:

      

      

        <1>List有序、可重复):List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所以插入删除数据速度慢。

          实现List接口的类主要有ArrayList,Vector,LinkedList,其存储性能和特性如下:

          ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了                                    synchronized方法(线程安全),通常性能上较ArrayList差,因此现在vector基本被ArrayList取代,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

          需要注意的是:

          1.对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。 
          2.对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。 
          3.查找操作indexOf,lastIndexOf,contains等,两者差不多。 

          List集合中常用的操作:

            add(Object)     添加一个Object元素; 

            remove(index)    删除给定索引的元素;

            get(index)      获取给定索引的元素;  

                 set(index, Object)    修改给定索引的元素为Object;

        <2>Set无序、不能重复):Set集合的基本特征是不记录添加顺序,不允许元素重复,只是简单地把对象加入集合中,最常用的实现类是HashSet。

          1.HashSet类直接实现了Set接口, 其底层其实是包装了一个HashMap去实现的。HashSet采用HashCode算法来存取集合中的元素,因此具有比较好的读取和查找性能。

            主要特征:           

            不仅不能保证元素插入的顺序,而且在元素在以后的顺序中也可能变化(这是由HashSet按HashCode存储对象(元素)决定的,对象变化则可能导致HashCode变化);

            HashSet是线程非安全的;

            HashSet元素值可以为NULL;

          2.TreeSet底层数据结构为二叉树,是一个有序的set集合,是线程不安全的;

          3.LinkedHashSet是HashSet的一个子类,LinkedHashSet也根据HashCode的值来决定元素的存储位置,但同时它还用一个链表来维护元素的插入顺序,插入的时候即要计算hashCode又要维护链表,而遍历的时候只需要按链表来访问元素。

          需要注意的是: 

          HashSet和TreeSet是Set集合中用得最多的集合。HashSet总是比TreeSet集合性能好,因为HashSet不需要额外维护元素的顺序。

          LinkedHashSet需要用额外的链表维护元素的插入顺序,因此在插入时性能比HashSet低,但在迭代访问(遍历)时性能更高。因为插入的时候即要计算hashCode又要维护链表,而遍历的时候只需要按链表来访问元素。

          Set集合中常用的操作:

          

            add(Object)     往set中添加元素使用的是add()方法,但是在set中没有add(index , element)方法; 

            remove(Object)     删除具体的Object元素;

          查(无此方法)   

          改(需要自己写工具类)       如下:

                            public Set<Object> updateSetValue(Set<Object> oldSet) {

                                  Set<Object> newSet = new HashSet<Object>();

                                  for (Object s : oldSet) {  

                                  if (s != "你要修改前的值") {

                                    newSet.add(s);

                                                 } else {

                                    newSet.add("你要修改后的值");

                                                    }

                                                    }

                                    return newSet;

                                                    }

        <3>Map键值对、键唯一、值不唯一):Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。HashMap为常用的实现类。

            实现类:HashMap、Hashtable、LinkedHashMap和TreeMap

         1.HashMap (底层数据结构哈希表)

           HashMap是最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。因为键对象不可以重复,所以HashMap最多只允许一条记录的键为Null,允许多条记录

         的值为Null,是非同步的(非同步就是线程不安全)

         2.Hashtable (底层数据结构哈希表)

           Hashtable与HashMap类似,是HashMap的线程安全版,它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢,它继承自Dictionary类,不同的是它不允许记录的键或者值为null,同时效率较低。

         3.ConcurrentHashMap(不常使用)

           线程安全,并且锁分离。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。

         4.LinkedHashMap(不常使用)

           LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候会比HashMap慢,有HashMap的全部特性。

         5.TreeMap(底层数据结构二叉树)

           TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序(自然顺序),也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。不允许key值为空,非同步的;

        Map集合中常用的操作:

        添加               put(key,value):当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回null。

 

        删除             clear():清空

                               remove(key) :删除指定键。

        判断        boolean isEmpty():

                   boolean containsKey(key):是否包含key

                   boolean containsValue(value) :是否包含value 

        取出      int size():返回长度

                   get(key) :通过指定键获取对应的值。如果返回null,可以判断该键不存在。当然有特殊情况,就是在hashmap集合中,是可以存储null键null值的。

                   Collection values():获取map集合中的所有的值。 

        map元素的遍历:

               HashMap map = new HashMap();

                map.put("ZH", "中国");

                map.put("EN", "英国");

                map.put("ZH1", "中华人名共和国");

              Set<Map.Entry<String,String>> set = map.entrySet();

                for (Entry<String, String> entry : set) {

                System.out.print(entry.getKey()+"----");

                System.out.println(entry.getValue());

                                  }

                输出结果:

                      EN----英国

                      ZH----中国

                      ZH1----中华人名共和国

二、数组与集合的区别:

    1、数组声明了它容纳的元素的类型,而集合不声明。

       2、数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。

          3、数组不论是效率还是类型检查都是最好的。

     4、数组的存放的类型只能是一种,集合存放的类型可以不是一种(不加泛型时添加的类型是Object);

     5、数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查,都是最快的,ArrayList就是基于数组创建的容器类。

     6、数组最大的弱点就是功能太弱小,所有才会有其他容器的出现。

posted @ 2017-12-08 09:24  天空VS  Views(1470)  Comments(0)    收藏  举报