java集合与框架

来源:互联网 发布:File_priv mysql 编辑:程序博客网 时间:2024/06/07 02:54

JAVA集合类型

集合
Collection接口

  • 是List、Set和Queue接口的父接口
  • 定义了可用于操作List、Set、Queue的方法(增删改查)

一、List(接口)

特点:

  • 先后顺序敏感,LIST结构中的元素必须分出谁先谁后。
  • 可以重复

主要用来模拟队列(queue)等生活中对先后顺序敏感的应用场景。

(1)ArrayList (以数组为基础实现)

数组在使用上较为麻烦,ArrayList是一个类,其对数组进行了2次改造,或者说在数组的基础上进行了二次开发,从使用角度克服了数组的诸多缺点,但本质上还是依靠数组机制来完成。

ArrayList内部依赖的是一个对象数组Object[], 其有众多方法,均围绕该对象数组展开:

    size()           获得arraylist中内部的实际包含元素的数量。    add()            追加到最后一个    add(index,obj)   插入数据到index所指定的下标位置    remove(index)    删除指定index位置的元素    remove(obj)      删除与该对象匹配的元素 (依靠equals匹配)    contains(obj)    查看是否存在该元素    indexOf(obj)     查看元素出现的索引位 (从头开始查)    lastIndexOf(obj) 查看元素出现的索引位 (从末尾开始查)    isEmpty()        查看arraylist是否存在有效元素    subList()        创造子List    toArray()        把List转数组    trimToSize       缩小容量到实际元素大小。      

优点:
与数组类似,随机定位速度很快.
但在编码便捷性上大大优于数组,少写不少控制代码。

缺点:
与数组类似,插入和删除容易造成大幅波动,在元素力量超出范围的时候,也有大量的数组元素拷贝的操作发生,对系统性能有较大影响。

适用场景:
1)数据录入后,较为稳定,删除和插入操作较少,大多为定位查询操作
2)数据增加的频率间隔较长,不会持续性连续增加
3)适合队列等对元素的先后顺序极为敏感的数据结构。

    ArrayList的遍历    1. 常规遍历法         for(int i=0;i<al.size();i++)          System.out.println(al.get(i)):    2. 集合类型专用遍历法 (jdk1.5以上版本支持)        for(Object obj:al)          System.out.println(obj);    3. 迭代体(iterator)遍历法        Iterator itr=al.iterator();           while(itr.hasNext())                System.out.println(itr.next());

【注】 ArrayList的泛型(generic type)控制
由于ArrayList很灵活,内部可以放置各种数据类型,导致外部程序,从ArrayList中取出一个元素,还必须谨慎对其判断, 有的时候外部需要大量的各种类型的代码来针对不同的对象进行对应操作,成本高昂。 有的程序员忘记书写了一些代码,经常会导致ClassCastException, 所以后来,人们不得不限制了ArrayList中的元素的类型,要求其内部只能有一种元素。

(2) LinkedList (以链表为基础实现)

优点:
与链表类型,插入和删除性能优越,不会造成内存波动。

缺点:
与链表类似,随机定位速度慢,需要从头开始依次检索.
链表的内存消耗大

适用场景:
1)数据录入后,较为不稳定,有着频繁删除和插入操作,随机定位查询相对较少。
2)适合队列等对元素的先后顺序极为敏感的数据结构。

二、 Set(接口)

特点:
1.Set是Collection接口的子接口,其继承了Collection接口中的所有抽象方法,并做了针对Set应用的方法扩展。
2.Set接口强调不可重复,但无先后顺序。

(1)HashSet

根据Hash (哈希) 算法进行内存分配,对数据进行保存的集合类型,对于装入其中的元素,保存在内存的位置,用户不用关心,保存的方式肯定是高效的,这是用哈希算法保证的,但有一点,不能重复! 对于插入其中的元素,HashSet不保障其先后顺序。

HashSet如何对插入的元素进行雷同识别?

->理解Object.hashCode()
Object对象有一个hashCode方法,该方法是本地方法,由C语言实现,返回的是这个对象在内存中的开始地址,返回值是一个整数。

任何对象如果其没有重写Object的hashcode方法,那么其hashcode的值均是不同的。

->HashSet依靠hashcode的返回值来判断对象是否相等
1.当一个对象被尝试保存入hashset的时候,hashset会先调用这个对象的hashcode方法返回一个hashcode值, hashset把该值与其内部的hashcode列表(该表保存了所有保存在hashset中的对象的hashcode值)进行比对, 如果发现没有相同,则认为该对象在hashset中没有重复,可以接纳。
2.如果发现对象的hashcode与列表中的一个对象雷同,那么hashset将会调用该对象的equals方法进行是否相同的最终判断。Equals认为不同,hashset还是会接纳该对象。

Object有equals和 hashcode两个方法进行对象内容是否相等的判断操作,在普通的应用中,一般我们用equals进行判断即可,但hashset由于其特性上需要保持不相同,所以其经常进行对象是否相同的判断,由于集合类型对性能要求很高,而equals判断涉及到较为复杂的逻辑,成本很高,在某种程度上会降低性能,但equals判断也是精度最高的判断。

从性能角度出发,Object还提供了轻量级的判断方法, hashcode. 由于hashcode内部只是整数运算,而底层还是C的,速度很快。

Hashcode认为不相同,则对象为不同的对象,equals就不介入的。
Hashcode认为相同,则交由equals做最后判断,equals结果为最终结果,可以推翻hashcode的判定结果。

Hashcode是“地方法院”, equals是“终审法庭”。

->hashcode 和equals 之间的契约
由于hashcode和equals方法之间有着主从关系,特别如果一个对象最终要与hashset打交道的时候, 就必须同时重写hashcode和equals方法,两个方法在重写的时候,必须保证一个约定,否则将重写失败!
契约:
1.Hashcode不同, equals一定要不同
2.Hashcode相同, equals可以不同

(2)TreeSet (树结构集合)

TreeSet里头的元素是不能重复的,但会根据某种既定的规则(天然顺序)进行排序输出。

所有加入TreeSet中的对象必须实现Comparable接口,
该接口只有一个方法int compartTo(obj);

返回值:
1)1当前对象大于传入对象
2)0当前对象等于传入对象
3)-1 当前对象小于传入对象

三、Map(接口)

Map提供了一种映射关系,其中的元素是以键值对(Key-value)的形式存储的,能够实现根据key快速查找value。

  1. map中的键值对以Entry类型的对象实例形式存在
  2. 键(Key值)不可重复,value值可以
  3. map接口提供了分别返回key值集合、value值集合以及entry(键值对)集合的方法
  4. map支持泛型,形式如:Map

(1)HashMap类

HashMap:
1. 数组方式存储key/value
2. 线程非安全
3. 允许null作为key和value,key不可以重复,value允许重复
4. 不保证元素迭代顺序是按照插入时的顺序,key的hash值是先计算key的hashcode值,然后再进行计算,每次容量扩容会重新计算所有key的hash值,会消耗资源,要求key必须重写equals和hashcode方法

(2)TreeMap类

TreeMap:
1. 基于红黑二叉树的NavigableMap的实现
2. 线程非安全
3. 不允许null,key不可以重复,value允许重复
4. 保证元素顺序,但是按照自然顺序排序,而不是插入时候的顺序
5. 可以自定义输出顺序从大到小或者从小到大
如:Map<Double, List> tmap = new TreeMap<Double, List>(Collections.reverseOrder());