21、为什么会有StringBuilder这个类?
在某些时候我们会有个需求——用较短的字符串构建一个长的字符串。比如按键和一篇文章中的单词。如果使用字符串连接,可以达到我们想要的效果,但是因为每一个新的字符串都需要创建一个实例,效率较低。即耗时,又浪费空间。所以有了StringBuilder这个类。
使用方法:
首先:创建一个空的字符串链接器:StringBuilder builder = new StringBuilder();
然后:每当要往里面加入新的短字符串(或字符)的时候,调用append方法:builder.append(ch);builder(str);
最后:当要将小字符串连接到一起时,调用toStrin方法:String allStr = builder.toString();
StringBuilder前生是StrinBuffer。StringBuffer的效率稍低,但允许多线程。所以如果是单线程的编辑选择StringBuilder。
22、安全的从控制台读取密码
一般我们在写程序时,接收键盘上输入的内容都采用Scanner。但是这种输入是可见的,密码被别人看见显然时不安全的
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("请输入内容。");
String str = sc.nextLine();
System.out.println("输入的内容为:"+str);
}
}
运行结果:
可以看见,我们输入的密码(蓝字)别人是很容易看见的。
为此Java SE6特别引入了Console类实现密码的安全输入。
import java.io.Console;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Console cons = System.console();
System.out.println("请输入内容。");
String userName = cons.readLine(/*"使用者姓名:"*/);//显示“使用者姓名:”,并且读取用户输入,直到输入行结束。
char[] password = cons.readPassword(/*"使用者密码:"*/);//同上。存入char是为了安全。
System.out.println("输入的内容为:"+userName+" "+password);
}
}
上面的代码是对的,但是如果你运行的话,结果是这样的。
不要怀疑自己的代码,它没问题。控制台也没问题。问题Console就是安全的不能在控制台中输入输出。
所以要在cmd环境下运行 别人cmd环境下的Dos命令操作示范:链接
23、Java 的格式化输出
Java SE 5.0 沿用了C语言库中的printf函数,所以使用起来与类似。
首先我们需要了解2个东西:
1、用于printf的转换符:就是告诉Java一会你想以什么样的格式输出(比如,十进制、二进制、定点浮点、散列码等)
2、用于printf的标志:就是告诉Java一会输出的时候有什么特殊的要求没有(比如,打印正负符号,左对齐、将负数包含在括号里等)
举例:
package allHere;
import java.io.Console;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a = 200;
float b = 4001.23456f;
System.out.printf("a=%x和b=%g",a,b);//将a以十六进制输出,将b以通用浮点输出。
}
}
结果:a=c8和b=4001.23(通用浮点就是xxxx.xx浮点数保留2位有效小数位,四舍五入)
举例:
package allHere;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a = -20000;
int b = 20000;
float c = 4001.0f;
float d = 4001.0f;
System.out.printf("a=%(,db=%(,d和c=%.0f和d=%#.0f",a,b,c,d);
//将a,b以千分位,复数用括号里的方式输出。
//c用0位小数方式输出,d用0位小数,但强制显示小数点方式输出。
}
}
结果:a=(20,000)b=20,000和c=4001和d=4001.
Java为了输出时间方便,还特意定义了专属于时间和日期的转换符。
加上$这个符号的参数索引,就能很灵活的输出你想要的日期格式。
举例:
package allHere;
import java.util.Date;
public class Test {
public static void main (String[] args) {
// TODO Auto-generated method stub
System.out.printf("%1$s %2$tY %2$tB %2$te, %2$tY", "今天是:", new Date());
}
}
//%1$s:%后面开始参数替换、1是参数索引值、$printf标志中的参数索引标志、s字符串类型
//%2$tY:%后面开始参数替换、2是参数索引值、$printf标志中的参数索引标志、t是printf转换符中的日期时间转换符、Y是代表年份的日期时间转换符(t是printf的转换符,Y是日期和时间的转换符Date()类型)
下同。(“今天是:”是第一个参数,new Date()是第二个参数。不同参数索引间用空格分开,以%开始$结束)
24、简单的文件输入和输出
输入:Scanner in = new Scanner(Path.get("myfile.txt","UTF-8"));
Path.get():获取文件路径(需在同级目录),“UTF-8”,编码格式,不写编码格式,默认UTF-8。
输出:PrintWriter out = new PrintWriter("myfile.txt","UTF-8");没有此文件夹则创建
PrintWriter:可以像输出到System.out一样使用print、println、printf。
容易出现的2个错误:1、用一个不存在的文件输入 2、输出到一个访问受限制的文件。都会发生异常。
25、像C中goto语句一样的带标签的break和coutine。
大家肯定知道goto,是Java保留关键字。也肯定知道break(学switch的时候,肯定会知道),但却不一定知道break可以带标签。
语法格式:
标签命:
某个循环名(while,for,switch){
代码1;代码2;……
break 标签名;
}
here:
while(true){
i++;System.out.println(i);
break here;//直接结束循环跳到here:
}
不同点:带标签的break只能跳出循环,不能像goto一样跳入。
带标签的break适用于多层循环嵌套,一个循环,break和带标签的break没什么区别。
continue是结束本次循环,带标签用法类似break。
26、循环中检测两个浮点数是否相等需要格外小心。
for(double x = 0; x != 10; x=x+0.1){……}像这个循环是死循环,因为0.1没法用二进制表示,所以x的精度丢失了,x实际上是由9.99999999999998增加到10.09999999999998是不会变成10的。
27、case标签
case标签在1.5前只能用整数、枚举(非long),1.5-1.6增加了char型,1.7增加了String(众望所归的字符串)。
28、程序内存消耗和耗时(RunTime类)
耗时:
long d1 = System.currentTimeMillis();//运行程序前,此刻的时间精确到毫秒
//程序执行;
long d2 = System.currentTimeMillis();//运行程序后,此刻的时间精确到毫秒
System.out.printf("耗时:%ss\n",d2-d2);//前后时间一减,就是程序运行的时间
内存消耗:。
public static void main (String[] args) {
// TODO Auto-generated method stub
Runtime r = Runtime.getRuntime();
long freeMemory = r.freeMemory();
long totalMemory = r.totalMemory();
long maxMemory = r.maxMemory();
int availableProcessors = r.availableProcessors();
System.out.println(freeMemory);
System.out.println(totalMemory);
System.out.println(maxMemory);
System.out.println(availableProcessors);
//getRuntime():该方法用于返回与当前 Java 应用程序相关的运行时对象。
// freeMemory():该方法用于返回Java虚拟机中的空闲内存量,以字节为单位。
// totalMemory():该方法用于返回Java虚拟机中的内存总量。
// maxMemory():该方法用于返回Java虚拟机试图使用的最大内存量。
//availableProcessors(): 向 Java 虚拟机返回可用处理器的数目。 ()
/*
运行结果:
59349328
64487424
652476416
8
*/
}
也可以使用jdk自带的:JConse。在命令行输入JConse就可以弹出windows页面了。虽然功能相比于其它软件不够强大,但胜在稳定。
一次更新几个问题不固定,根据文章内容长度更改:
Java中遇到的一些常识性小问题(1~20):链接
Java中遇到的一些常识性小问题(21~30):链接