这下明白了capacity()和length()的关系,前者是最大容量,默认是16,length返回当前长度。如果学过《数据结构》相关的课程并用到过extern void *realloc(void *mem_address, unsigned int newsize);就更容易理解了。如果字符串超过16个字符呢?我们修改代码如下:
1 public class StringBufferDemo{
2 public static void main(String [] args){
3 StringBuffer buffer = new StringBuffer();
4 buffer.append('S');
5 buffer.append("tringBuffer");
6// System.out.println(buffer.charAt(1));
7 System.out.println(buffer.capacity();
8// System.out.println(buffer.indexOf("tring12345"));
9 System.out.println("buffer = " + buffer.toString());
10 System.out.println(buffer.length());
11 }
12}
程序运行结果如下:
34
buffer = StringBuffer
17
哦,超过16个字符会再分配18个字符的空间。那超过34个字符呢?你猜猜capacity()的返回值(52?54?56?还是其他值)并修改上面的代码验证一下。
其实学习Java中的任何一个新类时,首先要学习一下其构造方法,我们看一下StringBuffer的构造方法,如下图:
汉化版如下:
原来我们可以构造StringBuffer时指定其capacity的,如果不指定默认值是16,我们修改代码如下:
1 public class StringBufferDemo{ 2 public static void main(String [] args){ 3 StringBuffer buffer = new StringBuffer(20); 4 buffer.append('S'); 5 buffer.append("tringBuffer"); 6// System.out.println(buffer.charAt(1)); 7 System.out.println(buffer.capacity(); 8// System.out.println(buffer.indexOf("tring12345")); 9 System.out.println("buffer = " + buffer.toString()); 10 System.out.println(buffer.length()); 11 } 12} |
程序运行结果如下:
20
buffer = StringBuffer
12
这时对capacity的理解是不是更深入了?
当然,如果能想到StringBuilder和String有什么不同,到网上找一下类「《全面解释java中StringBuilder、StringBuffer、String类之间的关系》」这类的文章看看就更积极主动了。
对于Java API中的类、方法,我们学习时写个测试类很利于我们理解类和方法的功能。我们在实验二 Java面向对象程序设计中学习了单元测试和JUnit,使用JUnit改写教材上的例子是积极主动敲代码的好途径。
比如下面这个代码,equals方法的代码要好好理解。equals实现了等价关系,满足:
自反性 (reflexive):对于任何一个非null的引用值x,x.equals(x)为true。
对称性 (symmetric):对于任何一个非null的引用值x和y,x.equals(y)为true时y.equals(x)为true。
传递性 (transitive):对于任何一个非null的引用值x、y和z,当x.equals(y)为true 且 y.equals(z)为true 则 x.equals(z)为true。
一致性 (consistent):对于任何一个非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)的结果依然一致。
另外还要满足:对于任何非null的引用值x,x.equals(null)必须返回false。
public class Score { private int No; //学号 private int score; //成绩 public ScoreClass() { //无参数的构造方法 No = 1000; score = 0; } public ScoreClass(int n, int s) { //有两个参数的构造方法 No = n; score = s; } public void setInfo(int n, int s) { //设置成绩 No = n; score = s; } public int getNo() { return No; //获取学号 } public int getScore() { return score; //获取成绩 } @Override public String toString() { return No + "\t" + score; } @Override public boolean equals(Object obj) { if (this == obj) { // 是否引用同一个对象 return true; } if (obj == null) { // 是否为空 return false; } if (getClass() != obj.getClass()) { // 是否属于同一个类型 return false; } ScoreClass other = (ScoreClass) obj; if (other.No == No && other.score == score) { return true; } else { return false; } } } |
参考极简单元测试示例(以除法为例),在你熟悉的Java IDE中(Intellij IDEA、Eclipse或NetBeans)中利用JUnit写一些测试代码,要求能测到equals中的每一个return,动手试试吧!
当然,积极主动是一种学习态度,看看学姐在我另一门课如何积极主动学习的「对atime、mtime和ctime的研究」,我说多思考了吗?深度思考对一个人的成长太重要了。