堆栈空间分配html
栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操做的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,须要读数据的时候从栈顶开始弹出数据。栈是只能在某一端插入和删除的特殊线性表。用桶堆积物品,先堆进来的压在底下,随后一件一件往上堆。取走时,只能从上面一件一件取。读和取都在顶部进行,底部通常是不动的。栈就是一种相似桶堆积物品的数据结构,进行删除和插入的一端称栈顶,另外一端称栈底。插入通常称为进栈,删除则称为退栈。 栈也称为后进先出表。
java
Heap
程序员
堆(heap)又被为优先队列(priority queue)。尽管名为优先队列,但堆并非队列。回忆一下,在队列中,咱们能够进行的限定操做是dequeue和enqueue。dequeue是按照进入队列的前后顺序来取出元素。而在堆中,咱们不是按照元素进入队列的前后顺序取出元素的,而是按照元素的优先级取出元素。算法
这就好像候机的时候,不管谁先到达候机厅,老是头等舱的乘客先登机,而后是商务舱的乘客,最后是经济舱的乘客。每一个乘客都有头等舱、商务舱、经济舱三种个键值(key)中的一个。头等舱->商务舱->经济舱依次享有从高到低的优先级。sql
java.lang.Object java.util.AbstractCollection<E> java.util.AbstractList<E> java.util.Vector<E> java.util.Stack<E>
public class Stack<E>
extends Vector<E>api
Stack
类表示后进先出(LIFO)的对象堆栈。它经过五个操做对类 Vector 进行了扩展 ,容许将向量视为堆栈。它提供了一般的push 和 pop 操做,以及取堆栈顶点的 peek 方法、测试堆栈是否为空的 empty 方法、在堆栈中查找项并肯定到堆栈顶距离的search 方法。数组
首次建立堆栈时,它不包含项。缓存
Deque
接口及其实现提供了 LIFO 堆栈操做的更完整和更一致的 set,应该优先使用此 set,而非此类。例如:安全
Deque<Integer> stack = new ArrayDeque<Integer>();
若是你的应用中涉及到的东西比较耗内存的话,好比:相机、第三方地图、腾讯、新浪、录音、视频播放、大量图片时,若是这些东西同时存在于应用中时,会有不少奇怪的问题出现,自动退出还不报错等等一系列的问题,还有,若是咱们的应用中使用startActivity()过多并且并无及时finish()掉的话,也会出现这样那样的问题,好比:退出应用时没有退出干净,或者莫名其妙的报OOM,启动的服务自动挂起什么的! 其实,Google已经提供了一套完整的机制让开发人员控制活动栈与任务栈
像这样的跳转咱们在开发的过程当中算是很长见到的了,在这里我就不贴代码了 ,假如就是有三个活动窗口(Activity1,Activity2,Activity3,)按前后顺序 从Activity1--startActivity()
到Activity2再到Activity3这个过程你们应该能够想象的到,在这个过程生成的活动堆栈如图所示:
数据结构
若是是点击回退键的过程当中也会有不同一样点击了六次按钮以后按的返回键,第一种效果必须点击六次Back键后方可退出,而第二种效果只点击一次便可退出,这就是Flag的魅力,激动….再来看Flag都有哪几种吧,此处我列在这个地方,上面两个效果中设置的是:i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);另外还有不少能够控制活动堆栈与任务栈的Flag,小马在这个地方随便列出两个,剩余的Flag值以截图的形式显示,节约时间:
Task就像一个容器,而Activity就至关与填充这个容器的东西,第一个东西(Activity)则会处于最下面,最后添加的东西(Activity)则会在最低端。从Task中取出东西(Activity)则是从最顶端取出。
2、界面跳转和服务的启动都会用到Intent,如今介绍Intent Flag是关于Activity的跳转
Intent intent = new Intent(this,xxx.class);
//若是activity在task存在,拿到最顶端,不会启动新的Activity
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
//若是activity在task存在,将Activity之上的全部Activity结束掉
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//默认的跳转类型,将Activity放到一个新的Task中
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//若是Activity已经运行到了Task,再次跳转不会在运行这个Activity
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
若是加了 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);操做下任务堆栈就能够了,具体的缘由,也能够用一句话来总结:若是在一个Activity中同一时间,要操做不用的功能,好比:跳转时还要操做视频录音文件的播放什么的,都得设置新的任务栈来启动打开,若是不启动新任务栈的话,有时候会无原无端的显示空白还不报错!上面的错只是一个小点,小到能够忽略不讲,写在这是提醒你们,该加的时候必须加Flag,至于何时加,你们能够参照下官方的文档及下面小马贴出的官方文档中解释堆栈的图解,加以理解学习,以下所示:Figure2:很少解释,就是在A B 丙个任务堆栈,若是用户正在于B任务堆栈进行交互时,A在等待唤醒,反之则反
Figure3: 下面这个就好玩了,学习了下官方的文档,讲的是:不管启动了一个新的任务堆栈或者在同一堆栈中来启动一个活动,按返回键也仍是会返回到用户以前操做的Activity,若是以单例堆栈(相似单位模式)载入的话,就会在后台生成一个针对于此活动的单独的一个任务堆栈,当这个任务堆栈被唤醒到前台时,此时的返回堆栈中就包含了从前几个任务传递过来的栈顶的全部Activity,栈顶与栈底的显示关系若是下图:
这个地方顺带着讲下,在控制活动堆栈时方式只有一种,就是直接在.java文件中setFlag,若是是控制任务堆栈的话能够以addFlag或直接在全局配置文件中添加配置的方式来控制,你们能够直接在AndroidManifest.xml文件中activity节点中添加哪下属性:taskAffinity、launchMode、allowTaskReparenting、clearTaskOnLaunch、alwaysRetainTaskState、finishOnTaskLaunch,两种控制任务堆栈的方式换汤不换药,你们看我的习惯选择使用就能够了…切记,用的时候必定搞清楚你要加的标志位是什么意思,不要看到个task就addFlag,设置Flag是为了让应用更干净,控制更严密,若是加错了标志位,应用是不会报任何错的,只是出现怪异的跳转与关闭!!!
Stack是一个后进先出(last in first out,LIFO)的堆栈,在Vector类的基础上扩展5个方法而来
Deque(双端队列)比起Stack具备更好的完整性和一致性,应该被优先使用
Stack自己经过扩展Vector而来,而Vector自己是一个可增加的对象数组( a growable array of objects)那么这个数组的哪里做为Stack的栈顶,哪里做为Stack的栈底?
答案只能从源代码中寻找,jdk1.6:
经过peek()方法注释The object at the top of this stack (the last item of the Vector object,能够发现数组(Vector)的最后一位即为Stack的栈顶
pop、peek以及search方法自己进行了同步
push方法调用了父类的addElement方法
empty方法调用了父类的size方法
Vector类为线程安全类
综上,Stack类为线程安全类(多个方法调用而产生的数据不一致问题属于原子性问题的范畴)
结果:
Stack并不要求其中保存数据的惟一性,当Stack中有多个相同的item时,调用search方法,只返回与查找对象equal而且离栈顶最近的item与栈顶间距离(见源码中search方法说明)