动手动脑
- 请运行以下示例代码StringPool.java,查看其输出结果。如何解释这样的输出结果?从中你能总结出什么?
s0,s1,s2字符串的内容相同,实际占用的是同一空间,引用的是同一个对象,所以前两个为true。而第三个中。两个“Hello”分别开辟了新的空间,引用的不同的对象,所以为false。
总结:
- 在Java中,内容相同的字串常量(“Hello”)只保存一份以节约内存,所以s0,s1,s2实际上引用的是同一个对象。
- 编译器在编译s2一句时,会去掉“+”号,直接把两个字串连接起来得一个字串(“Hello”)。这种优化工作由Java编译器自动完成。
- 当直接使用new关键字创建字符串对象时,虽然值一致(都是“Hello”),但仍然是两个独立的对象。
为什么会有上述的输出结果?从中你又能总结出什么?
执行完s1+=”b”后,开辟新的空间来存储s1的内容”ab”,但此时s2内容仍然是”a”,所以s1==s2为false;第三句字符串”ab”是一个独立的常量,它与s1引用的字符串无关。
注意:字符串变量只是字符串的管理者,而非字符串本身。所有的字符串都是不可变的,对他们的操作结果都是制造新的字符串出来。
总结:
- 给字串变量赋值意味着:两个变量(s1,s2)现在引用同一个字符串对象“a”!
- String对象的内容是只读的,使用“+”修改s1变量的值,实际上是得到了一个新的字符串对象,其内容为“ab”,它与原先s1所引用的对象”a”无关,所以,s1==s2返回false;
- 代码中的“ab”字符串是一个常量,它所引用的字符串与s1所引用的“ab”对象无关。
- String.equals()方法可以比较两个字符串的内容。
2.请查看String.equals()方法的实现代码,注意学习其实现方法。
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
3.String类的方法可以连续调用:
String str="abc";
String result=str.trim().toUpperCase().concat("defg");
请阅读JDK中String类上述方法的源码,模仿其编程方式,编写一个MyCounter类,它的方法也支持上述的“级联”调用特性,其调用示例为:
MyCounter counter1=new MyCounter(1);
MyCounter counter2=counter1.increase(100).decrease(2).increase(3);
….
源码:
public String trim() { int len = value.length; int st = 0; char[] val = value; /* avoid getfield opcode */ while ((st < len) && (val[st] <= ' ')) { st++; } while ((st < len) && (val[len - 1] <= ' ')) { len--; } return ((st > 0) || (len < value.length)) ? substring(st, len) : this; }
public String toUpperCase() { return toUpperCase(Locale.getDefault()); }
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); }
代码:
1 //信1605-2 王金萱 20163588 2 public class MyCounter { 3 private int m; 4 public MyCounter(int m) 5 { 6 this.m=m; 7 } 8 public MyCounter increase(int a) 9 { 10 System.out.print(m+"+"); 11 this.m=m+a; 12 System.out.println(a+"="+this.m); 13 return this; 14 } 15 public MyCounter decrease(int a) 16 { 17 System.out.print(m+"-"); 18 this.m=m-a; 19 System.out.println(a+"="+this.m); 20 return this; 21 } 22 public static void main(String[] args) { 23 // TODO Auto-generated method stub 24 MyCounter counter1=new MyCounter(5); 25 MyCounter counter2=counter1.increase(100).decrease(2).increase(3); 26 } 27 28 }
执行结果:
课后作业1:字串加密
- 古罗马皇帝凯撒在打仗时曾经使用过以下方法加密军事情报:
请编写一个程序,使用上述算法加密或解密用户输入的英文字串。
- 设计思想
用户先选择是要加密还是解密。
加密:用户输入英文字串,程序根据密钥key=3将每个字母对应后移三位来达到加密的效果,输出加密后的英文字串。
解密:用户输入已加密的英文字串,程序根据密钥key=3将每个字母对应前移三位来达到解密的效果,输出解密后的英文字串。
2. 程序流程图
3. 源代码
1 //信1605-2 王金萱 20163588 2 import java.util.Scanner; 3 public class password { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 Scanner in=new Scanner(System.in); 8 int choose=0; 9 String mingwen,jiami; 10 char array1[]=new char[100]; 11 char array2[]=new char[100]; 12 String output=""; 13 do 14 { 15 System.out.println("请选择:1-加密 2-解密"); 16 choose=in.nextInt(); 17 if(choose==1) 18 { 19 //加密 key=3 20 System.out.println("请输入要加密的明文:"); 21 mingwen=in.next(); 22 array1=mingwen.toCharArray(); 23 24 for(int i=0;i<array1.length;i++) 25 { 26 if(array1[i]>='a'&&array1[i]<='z'||array1[i]>='A'&&array1[i]<='Z') 27 { 28 29 if(array1[i]>=97&&array1[i]<120||array1[i]>=65&&array1[i]<88) 30 { 31 array1[i]+=3; 32 output+=array1[i]; 33 } 34 else if(array1[i]>=120&&array1[i]<=122||array1[i]>=88&&array1[i]<=90) 35 { 36 array1[i]-=23; 37 output+=array1[i]; 38 } 39 } 40 else 41 { 42 System.out.println("请输入英文字母!"); 43 return; 44 } 45 } 46 System.out.println("加密后:"); 47 System.out.println(output); 48 } 49 else if(choose==2) 50 { 51 //解密 key=3 52 System.out.println("请输入密文:"); 53 jiami=in.next(); 54 array2=jiami.toCharArray(); 55 for(int i=0;i<array2.length;i++) 56 { 57 if(array2[i]>='a'&&array2[i]<='z'||array2[i]>='A'&&array2[i]<='Z') 58 { 59 60 if(array2[i]>=100&&array2[i]<=122||array2[i]>=68&&array2[i]<=90) 61 { 62 array2[i]-=3; 63 output+=array2[i]; 64 } 65 else if(array2[i]>=97&&array2[i]<100||array2[i]>=65&&array2[i]<68) 66 { 67 array2[i]+=23; 68 output+=array2[i]; 69 } 70 } 71 else 72 { 73 System.out.println("请输入英文字母!"); 74 return; 75 } 76 77 } 78 System.out.println("解密后的明文:"); 79 System.out.println(output); 80 } 81 else 82 { 83 System.out.println("输入错误!"); 84 } 85 }while(choose!=1&&choose!=2); 86 } 87 88 }
执行结果:
课后作业二
整理String类的Length()、charAt()、 getChars()、replace()、 toUpperCase()、 toLowerCase()、trim()、toCharArray()使用说明、阅读笔记。
Length():获取字串长度
charAt():获取指定位置的字符
getChars():获取从指定位置起的子串复制到字符数组中(它有四个参数)
replace():子串替换
toUpperCase()、 toLowerCase():大小写转换
trim():去除头尾空格:
toCharArray():将字符串对象转换为字符数组