java.util包中三个重要的接口及特点:List(列表)、Set(集合,集合中元素唯一)、Map(key-value,key唯一)。不同类的实现各有差异:是否同步,线程安全,是否有序
常用类继承树
Collection(所有集合类的接口)
List、Set方法都继承自Collection接口
Collections(操作集合的工具类)
它提供了许多方便的方法,包括求两个集合的差集,排序等
由于大部分的集合接口实现类都是不同步的,可以用Collections.synchronized*方法创建同步的集合类对象
List synList = Collections.synchronizedList(new ArrayList());
其实现原理就是重新封装new出来的对象,操作对象时用关键字synchronized同步
List(列表)
ArrayList、Vector是线性表,使用object数组作为容器存储数据,容量可以动态增长,两者的区别是:
ArrayList是非同步的,Vector是同步的,在不考虑多线程时使用ArrayList可以提高效率,
LinkedList是链表,链表随机位置插入、删除数据时比线性表快,遍历比线性表慢
ArrayList(非同步、非频繁删除时选择)、Vector(需同步时选择)、LinkedList(f非同步,频繁在任意位置插入、删除时选择)
Set(集合,保证容器内元素的唯一性)
Set相对于List、Map是最简单的一种集合。集合中的对象不按特定的方式排序,并且没有重复对象。
- 它不允许出现重复元素;
- 不保证集合中元素的顺序
- 允许包含值为null的元素,但最多只能有一个null元素
Set是一个接口,实例化Set可以采用下面的方式:
- HashSet: HashSet类按照哈希算法来存取集合中的对象,存取速度比较快
- TreeSet :TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序
HashSet(散列集)
HashSet通过Hash算法排布集合内的元素,所谓的Hash算法就是把任意长度的输入(又叫做预映射),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射。对于不同类型的信息,其散列值公式亦不完全相同。
当我们使用HashSet存储自定义类时,需要在自定义类中重写equals和hashCode方法,主要原因是集合内不允许有重复的数据元素,在集合校验元素的有效性时(数据元素不可重复),需要调用equals和hashCode验证。
TreeSet(树集)
TreeSet是一个有序集合,其元素按照升序排列,默认是按照自然顺序排列,也就是说TreeSet中的对象元素需要实现Comparable接口来实现自比较功能。TreeSet类中跟HashSet类一样也没有get()方法来获取指定位置的元素,所以也只能通过迭代器方法来获取
TreeSet虽然是有序的,但是并没有具体的索引,当插入一个新的数据元素的时候,TreeSet中原有的数据元素可能需要重新排序,所以TreeSet插入和删除数据元素的效率较低。
Map(存储键值对)
HashMap结构的实现原理是将put进来的key-value封装成一个Entry对象存储到一个Entry数组中,位置(数组下标)由key的哈希值与数组长度计算而来,如果数组当前下标已有值,则将数组当前下标的值只想新添加的Entry对象。
TreeMap是有Entry对象为节点组成的一颗红黑树,put到TreeMap的数据默认按key的自然顺序排序,new Treem时传入Comparator自定义排序。
HashMap 支持key=null 但是 Hashtable 不支持 key =null
HashMap和Hashtable的区别:线程安全性,同步,速度
HashMap是非同步的,所以在多线程的情况下是不安全的,但是速度比HashTable要快,HashMap的迭代器(Iterator)是fail-fast迭代器,而HashTable是enumeration迭代器,所以当有其他线程改变了HashMap的数据结构时会抛出异常,而迭代器本身的remove()方法不会抛出异常
HashTable是同步的,所以也是线程安全的,多个线程可以共享一个HashTable,在Java5提供了一个噢那currentHashMap,它是HashTable的替代,比HashTable的扩展性要好
注意点:
Fail-safe和iterator迭代器相关。如果某个集合对象创建了Iterator或者ListIterator,然后其它的线程试图“结构上”更改集合对象,将会抛出ConcurrentModificationException异常。
HashMap可以通过下面的语句进行同步:
Map m = Collections.synchronizeMap(hashMap);
附加:
final、finally、finalize的区别
final:如果一个类被final修饰,意味着该类不能再派生出新的子类,方法不能覆盖,不能作为父类被子类继承,一个类不能既被声明为abstract,又被声明为final,将变量或方法声明为final可以保证在使用的时候不被改变,只能在定义的时候,或者在构造方法的时候给它赋值。而且final方法只能被使用不能被重写
String类能否被继承?为什么?
答: 不能, String类的对象本身就是常量, 同时String类是被final修饰的.
finally:在异常处理时提供finally块来执行任何的清除操作,不过异常是否抛出,最后都会执行finally代码块,一般的关闭事务,结束线程等操作都放在finally代码块
finalize:是方法名,java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作,这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的