动手动脑1:请运行以下示例代码StringPool.java,查看其输出结果。如何解释这样的输出结果?从中你能总结出什么?
输出结果:
结论:在Java中,内容相同的字串常量(“Hello”)只保存一份以节约内存,所以s0,s1,s2实际上引用的是同一个对象。
编译器在编译s2一句时,会去掉“+”号,直接把两个字串连接起来得一个字串(“Hello”)。这种优化工作由Java编译器自动完成。当直接使用new关键字创建字符串对象时,虽然值一致(都是“Hello”),但仍然是两个独立的对象。再看。。。
为什么会有上述的输出结果?从中你又能总结出什么?
给字串变量赋值意味着:两个变量(s1,s2)现在引用同一个字符串对象“a”!
String对象的内容是只读的,使用“+”修改s1变量的值,实际上是得到了一个新的字符串对象,其内容为“ab”,它与原先s1所引用的对象”a”无关,所以,s1==s2返回false;代码中的“ab”字符串是一个常量,它所引用的字符串与s1所引用的“ab”对象无关。String.equals()方法可以比较两个字符串的内容。动手动脑2:请查看String.equals()方法的实现代码,注意学习其实现方法。
源代码:
public class StringEquals { /** * @param args the command line arguments */ public static void main(String[] args) { String s1=new String("Hello"); String s2=new String("Hello"); System.out.println(s1==s2); System.out.println(s1.equals(s2)); String s3="Hello"; String s4="Hello"; System.out.println(s3==s4); System.out.println(s3.equals(s4)); }}输出结果:
实现方法:首先为s1寻找String缓冲池内是否有与"Hello"相同值的String对象存在,此时String缓冲池内是空的,没有相同值的String对象存在,所以虚拟机会在String缓冲池内创建此String对象,其动作就是new String("Hello");。然后把此String对象的引用赋值给s1。接着为s2寻找String缓冲池内是否有与"Hello"相同值的String对象存在,此时虚拟机找到了一个与其相同值的String对象,这个String对象其实就是为s1所创建的String对象。既然找到了一个相同值的对象,那么虚拟机就不在为此创建一个新的String对象,而是直接把存在的String对象的引用赋值给s2。
动手动脑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 class test{
public static void main(String[] args) {
// TODO Auto-generated method stub String str="abc"; String result=str.trim().toUpperCase().concat("defg"); System.out.println(result); }}
结果:
ABCdefg
package test;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub MyCounter counter1=new MyCounter(); MyCounter counter2=new MyCounter(); counter1.set(1); counter2=counter1.increase(100).decrease(2).increase(3); System.out.println(counter2.data);//注意此处不能写成counter2,否选择输出结果为哈希值 }}
class MyCounter{ int data; public void set(int d) { data=d; } public MyCounter increase(int i) { MyCounter a=new MyCounter(); a.data=data+i; return a; } public MyCounter decrease(int d) { MyCounter a=new MyCounter(); a.data=data-d; return a; }}
结果:
102
整理String类的Length()、charAt()、 getChars()、replace()、 toUpperCase()、 toLowerCase()、trim()、toCharArray()使用说明。
Length():获取字串长度,字符串是一个对象,在这个对象中包含length属性,它是该字符串的长度,使用String类中的length()方法可以获取该属性值。
charAt():获取指定位置的字符
getChars():获取从指定位置起的子串复制到字符数组中(它有四个参数,1.被拷贝字符在字串中的起始位置 2.被拷贝的最后一个字符在字串中的下标再加1 3.目标字符数组 4.拷贝的字符放在字符数组中的起始下标)
replace():子串替换,通过String类的replace()方法,可以将原字符串中的某个字符替换为指定的字符,并得到一个新的字符串,该方法的具体定义如下:public String replace(char oldChar,char newChar)
toUpperCase()、 toLowerCase():大小写转换,在String类中提供了两个用来实现字母大小写转换的方法,它们的返回值均为转换后的字符串,其中toLowerCase()用来将字符串中的所有大写字母改为小写字母,,方法toUpperCase()用来将字符串中的所有小写字母改为大写字母。
trim():去除头尾空格,通过String类的trim()方法,可以通过去掉字符串的首尾空格得到一个新的字符串,该方法的具体定义如下:public String trim()
toCharArray():将字符串对象转换为字符数组
动手动脑4:古罗马皇帝凯撒在打仗时曾经使用过以下方法加密军事情报:
请编写一个程序,使用上述算法加密或解密用户输入的英文字串要求设计思想、程序流程图、源代码、结果截图。
源代码:
package Test;
import java.util.Scanner;public class test {
public static void main(String[] args) {
Scanner input=new Scanner(System.in); System.out.println("输入密报:"); String x=input.next(); int number =x.length(); char a[]=new char[number]; a=x.toCharArray(); System.out.println("加密之后:"); int i; for( i=0;i<number;i++) { if(a[i]=='X') a[i]='A'; else if(a[i]=='Y') a[i]='B'; else if(a[i]=='Z') a[i]='C'; else a[i]=(char)(a[i]+3); System.out.print(a[i]);} input.close(); }}
程序流程图:
输出结果:
设计思想:人输入一组字符串,在经过代码转换成整型,在原有基础上加上3再转换成字符输出。