历史文章目录
【cs61b】学习笔记day1
文章目录
- 历史文章目录
- List
- 两个小问题
- bits
- 声明一个变量
- 引用类型
- 方框和指针表示法
- 数组的实例化
- 链表
- SLList
List
两个小问题
思考下面两个代码分别输出什么
Walrus a = new Walrus(1000, 8.3);
Walrus b;
b = a;
b.weight = 5;
System.out.println(a);
System.out.println(b);
int x = 5;
int y;
y = x;
x = 2;
System.out.println("x is: " + x);
System.out.println("y is: " + y);
从下图可以看出,a和b指向的同一个实例,而x和y是两个独立的
bits
在计算机中,数字72和大写字母H都是以01001000来存储,那么java是如何区分他们的?
答: 以类型区分
在Java, 有8 八种基本类型: byte, short, int, long, float, double, boolean, char
当在Java中声明一个特定类型的变量时:
- 计算机预留了足够的比特来存储这种类型的东西。
- 示例:声明一个int会留出一个32位的“盒子”。
- 示例:声明一个double会留出一个64位的盒子。
- Java创建一个内部表,将每个变量名映射到一个位置。Java不会向保留框中写入任何内容。
- 为了安全起见,Java不允许访问未初始化的变量,也就是没有。
声明一个变量
Java语言不允许访问数据块的确切地址,与C语言不同,在C语言中,可以向语言询问数据块的确切地址。
Java的这个特性是一种权衡,对程序员隐藏内存位置使您无法控制,从而阻止进行某些类型的优化。它也避免了大量非常棘手的编程错误。在非常低成本计算的现代时代,这种权衡通常是值得的。
在声明变量时,Java不会向保留框中写入任何内容。换句话说,没有默认值。因此,Java编译器会阻止使用变量,直到使用=操作符将该框填满位之后。
When you writeyou are telling the Java interpreter to copy the bits from x into y
当写 y = x, 其实是告诉Java解释器将x中的位复制到y中。
引用类型
上面,我们说过有8种基本类型:byte、short、int、long、float、double、boolean和char。其他所有类型,包括数组,都不是基本类型,而是引用类型。
当我们使用new实例化一个对象(例如Dog, Walrus, Planet)时,Java首先为类的每个实例变量分配一个方框,并用默认值填充它们。构造函数通常(但不总是)用其他值填充每个框。
引用变量声明
当我们声明任何引用类型(Walrus、Dog、Planet、array等)的变量时,Java都会分配一个64位的盒子,无论对象是什么类型。64位盒中包含的不是关于对象的数据,而是内存中对象的地址。
方框和指针表示法
就像以前一样,很难解释引用变量中的一堆位,所以我们将创建一个简化的参考变量的方框符号如下:
如果一个地址全是零,我们将用null表示它。
非零地址将由指向对象实例化的箭头表示。
下面来解释最开头的问题,为什么a和b是一样的
Walrus a = new Walrus(1000, 8.3);
Walrus b;
b = a;
第一行执行完毕,我们得到下面的:
第二行执行完,得到下面的图片:
根据GRoE(黄金相等法则,就是说,在java中的 ‘=’ 是将等号右边的赋值给等号左边的变量),也就是说第三行是把a中存储的地址复制给b,所以b也是指向相同的实例。
当我们向函数传递值时,实际上是进行的值传递。
数组的实例化
存储数组的变量和其他变量一样都是引用变量。
考虑下面的声明:
int[] x;
Planet[] planets;
这两个声明都创建了64位的内存盒。
x只能保存int数组的地址,而planets只能保存Planet数组的地址。
实例化数组与实例化对象非常相似。例如,如果我们创建一个大小为5的整数数组,
如下所示:
x = new int[]{0, 1, 2, 95, 4};
然后new关键字创建5个32位的盒子,并返回整个对象的地址,以便分配给x。
如果丢失了与地址对应的位,则会丢失对象。
例如,如果特定Walrus的地址的唯一副本存储在x中,那么x = null将导致永久丢失该Walrus。这并不一定是一件坏事,因为您通常会决定不再使用某个对象,因此简单地丢弃引用是安全的。
链表
三种等价的表示链表的方法:
public class IntList {public int first;public IntList rest; public IntList(int f, IntList r) {first = f;rest = r;}
}
IntList L = new IntList(5, null);
L.rest = new IntList(10, null);
L.rest.rest = new IntList(15, null);
IntList L = new IntList(15, null);
L = new IntList(10, L);
L = new IntList(5, L);
用递归方法求链表长度
/** Return the size of the list using... recursion! */
public int size() {if (rest == null) {return 1;}return 1 + this.rest.size();
}
迭代求长度:
/** Return the size of the list using no recursion! */
public int iterativeSize() {IntList p = this;int totalSize = 0;while (p != null) {totalSize += 1;p = p.rest;}return totalSize;
}
SLList
IntList类中它的数据结构有一些裸露,即所有的方法、变量、构造方法都在一个类中。这不太符合Java语言创造数据结构的习惯。所以在这一章中,我们希望可以创造一件“衣服”,通过这个“衣服”,即中间类,架起外部类接触到内部数据结构的桥梁。
首先我们构造内部的数据结构IntNode类:
sllist增加了头节点
关于public和private,我们一般把类中的属性设置为private,不允许直接访问,提高了安全性