java数据结构:简介

数据结构

Java数据结构的知识体系主要包括线性表、树、图、数组、集合、矩阵、排序、查找、哈希表,并将Java的设计思想、方法以及一些常见的算法、设计模式贯穿其中;

1.【Collection接口:】

Collection

         |-List

|   —LinkedList

|   —ArrayList

|   —Vector

|     —Stack

|-Set

 

Map

  |-Hashtable

  |-HashMap

  |-WeakHashMap

接口的子接口:

List

Set

 

所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用户创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection和传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection;

不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代器,使用迭代器即可逐一的访问Collection中的每一个元素;

1.1【List接口】:有序的Collection

除了具有Collection接口提供的iterator()方法之外,List还提供了一个listIterator()方法,返回一个ListIterator接口。ListIterator方法多了一些添加、删除、设定元素,还支持向前或者向后遍历;

ArrayList:实现了大小可变的数组,允许所有元素,包括null

ArrayList没有同步,添加n个元素需要O(n)的时间。其他方法的运行时间为线性;

每一个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组大小;这个容量可以随着不断地添加新的元素而自动的增加,但是增长的算法并没有定义。当需要插入大量的元素的时候,在插入之前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入的效率;

 

与LinkedList一样,ArrayList也是非同步的(Unsynchronized)

 

1.1.1【Vector类】

Vector类非常类似于ArrayList类,但是Vector类是同步的。由Vector创建的Iterator,虽然与ArrayList创建的Iterator是同一个接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在使用的时候,另一个线程改变了Vector的状态(例如,添加或者删除了一些元素),这时候调用Iterator的方法时将抛出ConcurrentModificationException异常,因此必须捕获该异常;

 

1.1.2【Stack类】

Stack类继承自Vector类,实现了一个后进先出的堆栈。Stack类提供了5个额外的方法,使得Vector可以当做堆栈使用。有基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建之后是空栈;

1.2【Set接口】

Set接口是一种不包含重复元素的Collection,Set最多有一个null元素。很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素;

注意:必须小心的操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身的状态导致Object.equals(Object)= true,将导致一些问题;

1.3【Map接口】

Map接口没有继承与接口Collection,Map提供key到value的映射。一个Map中不能包含相同的key,每一个key只能映射一个value。

Map接口提供了3种集合的视图,Map的内容可以当做一组Key集合、一组value集合,或者一组key-value映射;

主要方法如下:

boolean equals(Object o):用于比较对象

boolean remove(Object o):用于删除一个对象

put(Object key,Object value)

 

1.3.1【Hashtable类】

Hashtable类继承与Map接口,实现一个key-value映射的哈希表。

任何非空(non-null)的对象都可以作为key或者value。

put方法和Get方法的时间开销为常数;

 

Hashtable通过initial capacity和load factor两个参数来调整性能。通常默认的load factor 0.75较好的实现了时间和空间的均衡。增大load factor可以节省空间,但是相应的,查找时间将增大,这会影响Get和put的这样的操作;

作为key的对象是通过计算其哈希函数来确定与之对应的value的位置。因此任何作为key对象都必须实现hashCode和equals方法;

根据哈希函数的定义:

如果两个对象相同,即obj1.equals(obj2)=true,则它们之间的hashCode必须相同;

但是如果两个对象不同,则它们的hashCode不一定不同;

如果两个不同对象的hashCode相同,这种现象称为冲突。冲突会导致操作哈希表的时间开销增大,所以应该尽量定义好hashCode方法,以便加快哈希表的操作;

 

如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的Get方法返回null)

要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个,因为Hashtable是同步的;

 

1.3.2【HashMap类】

HashMap类与Hashtable类相似,不同之处在于HashMap是非同步的,并且允许null,即null value和 null key。但是将HashMap视为Collection的时(values()方法可返回Collection),其迭代子操作时间开销与HashMap的容量成比例;因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设置的过高,或者load factor设置的过低;

1.3.3【WeakHashMap类】

WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC(垃圾回收器)回收;

 

注意:

如果涉及堆栈、队列等操作,应该考虑用List,对于需要快速插入、删除元素,应该使用LinkedList;

如果需要快速的随机访问元素,应该使用ArrayList。

单线程中使用非同步的类效率较高;多线程中应该使用同步的类;

作为key对象要正确的复写equals和hashCode方法;

尽量的返回接口,而不是实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList的时候,客户端代码不用改变。这就是针对抽象编程;

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值