java基础知识学习笔记(三)

Java集合

引言

在实现某个方法时,选择不同的数据结构,代码的简洁性与时间效率会有所不同,根据需要,选择合适的数据结构解决问题。比如要搜索很大数据量但是有序的数据(数组),或者在序列中间插入一个或删除一个元素(链表),或者需要建立键与值的关系(map),等等。以上一些数据结构在java中如何实现的?

接口的概念

在介绍接口之前,先给出一个java的集合框架图
这里写图片描述

简单说明一下:

短虚线表示的矩形框:接口(8个,下面的两个不属于集合范畴,不算)。

长虚线表示的矩形框:抽象类(5个),对接口的部分实现,方便类库的实现者。接口的方法很多,都实现太麻烦了,而抽象类中实现了接口的部分方法,只要在此基础上扩展就可以了。

实线表示的矩形框:实现类(10个,Collections和Arrays不算,这两个后面会提到)

抽象类可以不必掌握,对于使用者而言(实现者可以看看),所以可以把上面的框架图简化一下
这里写图片描述
对比上图说明一下:

抽象类去掉了,我们不考虑
标有legacy的也去掉了,遗留问题后面再讲
SortedSet,SortedMap,WeakHashMap去掉了
增加了LinkedHashSet,LinkedHashMap
这5个实现类后面会讲到

现在基本框架清晰了,开始讲接口。

接口与实现分离

java集合类将接口与实现分离,这是一种设计模式,接口模式或桥接模式,这里不细讲,感兴趣可以看看大话设计模式。举个简单例子,常见的队列(queue),在java中如何实现的呢?

interface Queue<E>//standard library
{
    void add(Element e);
    E remove();
    int size();
}

接口只是定义了队列,并没有讲队列如何实现。在java集合中队列有两种实现方式,就是前面的框架图中的ArrayDeque和LinkedList,为什么会是两种呢?

在这里引入一些数据结构的知识,帮助理解队列的实现。
队列作为一种线性表,存储方式(即实现方式)有两种,顺序存储和链式存储。先来看顺序存储。

假设队列中有n个元素,则顺序存储需要建立一个大于n的数组,把n个元素放在前n个位置,后面的空间方便添加元素。此时队头指向下标为0的元素。
入队:就是在队尾加一个元素,O(1)
这里写图片描述
出队:移除队头元素,并将后面的元素前移,O(n)
这里写图片描述

这就好比现实中排队买票,前面的人买好走了,后面的人自然要补上。但我们希望提高性能,如果不限制前n个位置存储元素(队头不固定在下标0),这样就不用移动后面的元素
这里写图片描述
这样的话就需要两个指针:front,rear
比如,长度为5数组,初始队列为空,front和rear指向下标0。然后a1,a2,a3,a4依次入队
这里写图片描述
出队a1,a2。然后入队a5
这里写图片描述
发现问题了,此时rear指向什么地方?
此时队列元素少于5个,但队尾已被占用,如果继续入队新元素,则会产生数组越界的错误,但前面0,1位置都是空的,这就是所谓的“假溢出”

如果你坐公交车,发现后排座位已满,但前面还有座位,你会怎么办?下车,然后说公交车满了,等下一班车吗?显然没有人会这么傻。

以上例子就是为了说明,数组方式实现队列,显然缺陷太多,所以数据结构里面提供了一种循环队列的方式。
前面的问题可以这样解决
这里写图片描述
此时入队a6,a7
这里写图片描述
这里有个问题:队列空,front==rear。现在队列满,front==rear

解决:

方法一:设置一个flag,
当front==rear,flag==0时,为空
当front==rear,flag==1时,为满

方法二:保留一个空间

这里写图片描述

这个时候,我们认为队列已经满了。
左边图:(rear+1)%QueueSize==front
右边图:(rear+1)==front
总结:(rear+1)%QueueSize==front时,队列满

队列的实际长度
左边图:rear>fornt,长度为rear-fornt
右边图:rear<fornt,长度为(QueueSize-front)+(rear-0)=rear-fornt+QueueSize
总结:长度为:(rear-fornt+QueueSize)%QueueSize

至于队列的链表实现,不再讲了,就是单链表,想看的同学可以去看看大话数据结构。

总之队列的实现无外乎就是以上讲的两种:循环数组和链表

class CircleArrayQueue<E> implements Queue<E>//只是举个例子
{
    CircleArrayQueue(int capacity){
  ...}
    public void add(Element e){
  ...}
    public E remove(){
  ...}
    public int size(){
  .
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值