字符串
String类是属于final的不可变类,String的类对象是不可变字符串,一旦被确定就不能修改其中的任何一个字符。当然,我们可以修改字符串的引用变量,让它引用另外的一个字符串。这种实现机制有一个最大的好处就是编译器可以让字符串共享。
具体的工作方式可以想象将各种字符创存放到一个公共的存储池中。字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符。因为String类属于不可变的类,所以涉及到需要改变其内容的拼接动作,都是需要借助StringBuilder完成。举个例子:
String str = "Hello";
str+=str1;
str+=str2;
str+=str3;
str的每次相加动作都new了一个新的StringBuilder对象,使用该对象的append方法完成拼接,再用toString()方法转换成string。
String str = "Hello";
str+=str1+str2+str3;
str在拼接时,new了一个StringBuilder对象, str1+str2+str3共操作append2次,+=操作append1次,总共3次。
由以上的对比分析,String类型的拼接借助StringBuilder完成,一次赋值操作会产生一个StringBuilder对象。
字符串比较
检测两个字符串是否是相等的一定不要使用“==”运算符,这个运算符只能够确定两个字符串是否是放置在同一个位置上。事实上,如果虚拟机始终将相同的字符串共享,就可以使用==运算符检测是否是相等的。但是,实际上只有字符串的常量是共享的,而+或subString等操作产生的结果并不是共享的。
如下代码的的执行结果:
String a = "abc";
String b = "abc";
System.out.println(a == b);
String c = "ab" + "c";
System.out.println(a == c);
String d = "c";
String e = "ab" + d;
System.out.println(a == e);
String f = "abcd".substring(0,3);
System.out.println(a == f);
执行结果:
true
true
false
false
空串“”是长度为0内容为空的字符串。
null串表示没有任何对象与该变量关联。
StringBuffer是线程安全的,但是执行效率低。StringBuilder是非线程安全的,但是执行效率高。
输入输出
读取输入
要想通过控制台进行输入,可以构造一个Scanner对象,并与标准输入流System.in关联。
Scanner in = new Scanner(System.in);
常见方法:
nextLine():输入一行,以回车结尾。
next():读取一个单词,以空格结尾。
格式化输出
Java沿用了C语言库函数中的printf方法。例如,对x=3333.3333333调用:
System.out.printf("%8.2f",x);
可以用8个字符的宽度和小数点后两个字符的精度打印x。也就是说会打印输出一个空格和7个字符,如下所示:
3333.33
可以使用静态的String.format方法创建一个格式化的字符串,而不打印输出:
String message = String.format("%s,you will be %d",name,age);
文件输入与输出
如果需要对文件进行读取,则需要使用File对象构造一个Scanner对象:Scanner in = new Scanner(Paths.get("file.txt"))
如果是想写入一个文件,就需要构造一个PrintWriter对象,在构造器中只需要提供文件名即可,如果文件不存在则会创建文件:
PrintWriter out = new PrintWriter("file.txt");
可以构造一个带有字符串参数的Scanner,但是这个Scanner将字符串解释为数据,而不是文件名。例如,调用:
Scanner in = new Scanner(“file.txt”);
这个Scanner会将参数作为包含10个字符的数据。