Java学习集合笔记

时间:2022-08-28 15:38:44
Java集合分为Set、Map、List、Queue
其中Set代表的是无序,不可重复的集合    List代表有序,重复集合    Map代表的是具有映射关系的集合


HashSet是Set接口的典型实现,大多数使用Set集合时都是使用这个实现类。HashSet按照Hash算法来存储集合中的元素,具有很好的存取

和查找性能。
    HashSet具有以下特点:
    不能保证元素的排列顺序,顺序可能与添加的顺序不相同。
    HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有多个线程同时修改了HashSet集合,必须通过代码来保证同步
    集合元素可以是null
注意:
    当把一个对象放入HashSet时,如果需要重写该对象对应类的equals()方法时,则也应该重写hashCode方法。
    规则是:如果两个对象通过equals()方法比较返回true,这两个对象的hashcode也应该相同
    如果两个对象通过equals()方法比较返回true,但是hashCode()方法返回的不同的hashCode,将导致HashSet会把两个对象
    保存在hash表的不同位置,从而两个对象都能添加成功,这就与Set的规则冲突了


TreeSet可以确保集合元素处于排序状态
    TreeSet并不是按插入数据的顺序进行排序的,有两种排序的方法:自然排序和定制排序
自然排序:TreeSet会调用compareTo(Object obj)方法比较元素的大小关系,然后将集合按升序排列
    大部分类在实现compareTo(Object obj)方法时,都需要将被比较的对象obj强制转化成相同类型。因为只有两个相同类的实例
    才会比较大小。所以说,如果希望TreeSet能正常进行工作,TreeSet只能添加同一种类型的对象。
    对于TreeSet集合而言,判断两个对象是否相等的唯一标准就是:两个对象通过compareTo(Object obj)方法比较是否返回为0,
     如果为0则认为他们相同,如果不为0则认为他们就是不相同。
注意:
    当需要把一个对象放入TreeSet中,重写该对象对应类的equales()方法时,应保证该方法与compareTo(Object obj)方法有一致
    的效果,规则是:如果两个对象通过equales()方法比较返回true,那么通过compareTo(Object obj)方法比较应该返回0
    如果通过compareTo(Object obj)方法比较应该返回0,通过equales()方法比较返回false会很麻烦,因为通过compareTo(Object obj)
    方法比较两个元素相同,TreeSet将不会让第二个元素添加进去。
定制排序:如果要实现定制排序,则需要在创建TreeSet集合对象时,提供一个Comparator对象与该TreeSet集合关联,由该Comparator
    对象负责集合元素的排序逻辑。


    HashSet的性能总是比TreeSet好(特别是添加、查询元素操作),因为TreeSet需要额外的红黑树算法来维护集合元素的次序,只有
   当需要一个排序的Set时用TreeSet,否则都用hashSet
    HashSet的子类LinkedHashSet,对于普通的插入和删除操作比HashSet要慢,这是由于维护链表所带来的额外开销造成的,但是
    遍历会更快一点。
    Set的3个实现类TreeSet、HashSet、EnumSet都是线程不安全的。如果有多个线程同时访问一个Set,并且有超过一个线程修改了Set
    则必须手动保证该Set集合的同步性。



List:
    List判断两个对象是否相等的条件是equals()方法返回 true 即可
    ArrayList和Vectory用法几乎相同,前者是线程不安全的,后者是线程安全的。



Queue:
    priorityQueue实现类保存队列元素并不是按照加入队列的元素,是按照元素的大小进行重新的排序
    Queue代表队列,Deque代表的双端队列
    Deque接口提供了一个典型的实现类ArrayDeque,它既可以作为栈来使用,也可以作为队列来使用。
    LinkedList、ArrayList、ArrayDeque的实现机制完全不同,ArrayList、ArrayDeque内部以数组的形式来保存集合中的元素,
   因此随机访问时会有较好的性能;而LinkedList内部以链表的形式保存元素,在随机访问方面性能较差,但是在插入、删除方面较好
   (只需要改变指针指向即可)

    一般来说数组是一块存储空间连续的存储,所以数组在随机访问时性能较好,所有的内部以数组作为底层实现的集合在随机访问
    时性能都比较好;而内部以链表作为底层实现的集合在插入、删除方面具有较好的性能。总体来说ArrayList性能比LinkedList性能好

    1.如果遍历list集合,对于ArrayList、Vector集合,应该使用随机访问的set方法比较好,对于LinkedList集合,则可以使用
     迭代器(Iterator)来遍历集合元素
    2.如果有多个线程同时访问List集合,考虑使用Collection将集合包装成线程安全的集合



Map:
     Map的key不允许重复,而且同一个Map对象的任何两个key通过equals()方法比较总是返回false
    Map和Set有密切联系,Map提供了Entry内部类来封装key-value对,而计算entry存储只需要考虑Entry封装的key

    HashMap和Hashtable存在两点典型的区别:
    1.Hashtable是一个线程安全的Map实现,但是HashMap是线程不安全的实现,所以HashMap的性能要好一点
    2.Hashtable不允许使用null作为key和value,如果试图把null值放进Hashtabe中,会引发异常,但是HashMap可以使用null
    作为key或者value
    HashMap和Hashtable判断两个key相等的标准是:两个key通过equals()方法返回true,两个Key的hashCode值也相等就算是
    相同的key,只要通过equals()方法返回为true,则认为value相等

    properties类是Hashtable类的子类,相当于是一个key,value都是string类型Map

    TreeMap就是一个红黑树的结构,每一个key-value对即作为一个红黑树的节点。TreeMap存储的key-value对(节点)时,需要
    根据key对节点进行排序。TreeMap也有两种排序方式:
     1.自然排序:TreeMap的多有key必须实现Comparable接口,而且所有的key应该是同一个类的对象
     2.定制排序:创建TreeSet时,传入一个Comparator对象,该对象负责TreeMap中所有key进行排序,采用定制排序不需要实现
      Comparable接口

    类似与TreeSet中判断两个元素相等的标准,TreeMap中判断两个key相等的标准是:两个key通过compareTo()方法返回0
    使用自定义类作为TreeMap的key时,应重写类的equals()方法和compareTo()方法时应保持一致的返回结果:
        两个key通过equals()方法返回true时,他们通过compareTo()方法比较应该返回0,否则可能引起冲突

各类Map性能总结分析:
    由于hashtable是一个古老的、线程安全得到集合,所以hashMap比hashtable要快。
    TreeMap通常比HashMap、Hashtable要慢(尤其是在插入、删除的时候),因为TreeMap底层采用红黑树来管理。
    TreeMap好处:TreeMap中的key-value总是处于一个相对有序的状态,无需进行专门的排序。当TreeMap被填充之后,可以
     调用keyset()方法,取得的key组成Set,然后用toArray()方法生出数组,再使用Arrays的binarySearch()方法在排序的数组中
     查找对象。

同步控制:
      Collections中提供了多个synchronizedXxx()方法,该方法可以将指定集合包装成线程同步的集合,从而解决多线程并发访问
    集合时的线程问题。
    Java中常用的集合框架HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap和TreeSet都是线程不安全的

         public static void main(String[] args){
        Collection c= Collections.synchronizedCollection(new ArrayList());
        List list =Collections.synchronizedList(new ArrayList());
        Set s =Collections.synchronizedList(new HashSet());
        Map m =Collections.synchronizedList(new HashMap());
}