黑马程序员技术交流社区

标题: Java中的堆和栈(整理) [打印本页]

作者: 被遗弃者    时间: 2012-11-14 11:10
标题: Java中的堆和栈(整理)
1 相同点:都是RAM中存放数据的地方  
2 不同点:  
  a.栈:存取速度快,但大小生命周期固定,主要应用于基本数据类型(byte,int,long,float,double,char,boolean)  
  b堆:存取速度慢,但能动态分配内存,主要应用于对象(new方式建立)  
3 示例:  
  int a=1;  
  int b=1;  
  那么在栈中只有一个1,a和b同时指向它,因此节省内存空间。  
同理: 如果  
String x = "one";  
  String y= "one";  
  则 x == y 返回 true,  
如果 String x=new String("one");  
String y= new String("one");  
则 x==y 返回false,因为前一个存在栈里面,引用同一个“one”,而后者存放在堆里,分别建立对象。  
4 与C++比较,java自动垃圾回收机制,因此堆栈都由系统分配,而C++中堆有程序员分配,而栈由系统分配。





  首先,明确两个概念:数据结构与数据存储结构!

数据结构: 是指相互之间存在一种或多种特定关系的 数据元素 的集合。听起来是不是很抽象,简单理解:数据结构就是描述对象间逻辑关系的学科。比如:队列就是一种先进先出的逻辑结构,栈是一种先进后出的逻辑结构,家谱是一种树形的逻辑结构!(初学数据结构的时候很不理解为什么有“栈”这个东西;队列很容易理解---无论购物就餐都需要排队;栈可以认为就是个栈道--- 只允许一个人通过的小道,而且只能从一端进入,然后再从这端返回,比如你推了个箱子进去啦,第二个人也推个箱子进去,此时只能等后进来的这个人拉着箱子出去后,你才能退出。)

数据存储结构: 它是计算机的一个概念,简单讲,就是描述数据在计算机中存储方式的学科;常用的数据存储方式就两种:顺序存储,非顺序存储!顺序存储就是把数据存储在一块连续的存储介质(比如硬盘或内存)上 ---- 举个例子:从内存中拿出第 100 个字节到 1000 个字节间的连续位置,存储数据;数组就是典型的顺序存储!非顺序存储就是各个数据不一定存在一个连续的位置上,只要每个数据知道它前面的数据和后面的数据,就能把所有数据连续起来啦;链表就是典型的非顺序存储啦!

    至此,基本就应该明白它们之间的区别了吧!

    队列、栈是线性数据结构的典型代表,而数组、链表是常用的两种数据存储结构;队列和栈均可以用数组或链表的存储方式实现它的功能!

//========================简单分析===============================

    数组属于顺序存储中,由于每个元素的存储位置都可以通过简单计算得到,所以访问元素的时间都相同(直接访问数组下标);链表属于数据的链接存储,由于每个元素的存储位置是保存在它的前驱或后继结点中的,所以只有当访问到其前驱结点或后继结点后才能够按指针访问到自己,访问任一元素的时间与该元素结点在链接存储中的位置有关。

    链表和数组是常用的两种数据存储结构,都能用来保存特定类型的数据。两者存在着一些差异:

1. 占用的内存空间

    链表存放的内存空间可以是连续的,也可以是不连续的,数组则是连续的一段内存空间。一般情况下存放相同多的数据数组占用较小的内存,而链表还需要存放其前驱和后继的空间。

2. 长度的可变性

    链表的长度是按实际需要可以伸缩的,而数组的长度是在定义时要给定的,如果存放的数据个数超过了数组的初始大小,则会出现溢出现象。

3. 对数据的访问

    链表方便数据的移动而访问数据比较麻烦;数组访问数据很快捷而移动数据比较麻烦。

    链表和数组的差异决定了它们的不同使用场景,如果需要很多对数据的访问,则适合使用数组;如果需要对数据进行很多移位操作,则设和使用链表。

上面提到的都是栈,而不是堆栈,那堆栈是什么呢?

首先,堆栈是计算机语言中常用术语,堆栈是栈的俗称!

    比如在Java中我们常常说堆栈什么什么的,其实就是说栈内信息!此时有人就问:Java中明明有堆和栈两个概念呀?!不错,堆和栈的确是两种不同的内存操作单元,它们用途不同,但堆栈就是栈的俗称,你可以理解它其实就是栈!

堆和栈有什么区别:

1. 栈具有数据结构中栈的特点,后进先出,所有存放在它里面的数据都是生命周期很明确(当然要求它不能存放太久,占有的空间确定而且占用空间小),能够快速反应的!所有在Java中它存放的是8个基本数据类型和引用变量的,用完就马上销毁

2. 堆可以理解它就是个一个可大可小,任你分配的听话的内存操作单元;因此它的特点就是动态的分配内存,适合存放大的数据量!比如一个对象的所有信息,虽然它的引用指向栈中的某个引用变量;所有Java中堆是存放new出来的对象的。

    堆和栈因为不同的特性,所有在计算机中应用甚广

作者: 陈龙    时间: 2012-11-14 12:07
同理: 如果  
String x = "one";  
  String y= "one";  
  则 x == y 返回 true,  
如果 String x=new String("one");  
String y= new String("one");  
则 x==y 返回false,因为前一个存在栈里面,引用同一个“one”,而后者存放在堆里,分别建立对象。

对于你上面的理解,我有点异议,大家一起来讨论一下;
String x = "one";  
  String y= "one";  
  则 x == y 返回 true,这个没有错
关键是你后面说它们是存在栈里面,这个有点问题,我觉得"one"还是存放在堆里

x,y都指向这个字符串,即x,y指向的堆内存地址相同,所以x==y才是true。

作者: 李连闯    时间: 2012-11-14 12:22
陈龙 发表于 2012-11-14 12:07
同理: 如果  
String x = "one";  
  String y= "one";  

表示赞同,以双引号赋值的String类型变量,String x = "one";中的"one"存在于常量池中,而常量池是堆的一部分,引用x是在栈中的;
作者: 初艳春    时间: 2012-11-14 12:25
有水平,值得学习!{:soso_e179:}
作者: 奚华    时间: 2012-11-16 10:45
哈哈,学习了!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2