集合与数组详解
⼀、数组与集合的基础介绍:
  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.());
                                      }
     (2)下图详细介绍了集合类的接⼝,及接⼝实现类集合的特点:
indexof能用于数组吗        <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 = Set();
                for (Entry<String, String> entry : set) {
                System.out.Key()+"----");
                System.out.Value());
                                  }
                输出结果:
                      EN----英国
                      ZH----中国
                      ZH1----中华⼈名共和国
⼆、数组与集合的区别:
   1、数组声明了它容纳的元素的类型,⽽集合不声明。
  2、数组是静态的,⼀个数组实例具有固定的⼤⼩,⼀旦创建了就⽆法改变容量了。⽽集合是可以动态扩展容量,可以根据需要动态改变⼤⼩,集合提供更多的成员⽅法,能满⾜更多的需求。
    3、数组不论是效率还是类型检查都是最好的。
    4、数组的存放的类型只能是⼀种,集合存放的类型可以不是⼀种(不加泛型时添加的类型是Object);
    5、数组是java语⾔中内置的数据类型,是线性排列的,执⾏效率或者类型检查,都是最快的,ArrayList就是基于数组创建的容器类。
    6、数组最⼤的弱点就是功能太弱⼩,所有才会有其他容器的出现。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。