1. 不可变String
String是不可变的,String类中每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改后的字符串内容。而最初的String对象则丝毫未动
public class Immutable {
public static String upcase(String s){
return s.toUpperCase();
}
public static void main(String[] args) {
String q = "howdy";
System.out.println(q);
String qq = upcase(q);
System.out.println(qq);
System.out.println(q);
}
}
当把q传给upcase()方法时,实际传递的是引用的一个拷贝。其实,每当把String对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。
回到upcase()的定义,传入其中的引用有了名字s,只有upcase()运行的时候,局部引用s才存在。一旦upcase()运行结束,s就消失了。当然了,upcase()的返回值,其实只是最终结果的引用。这足以说明,upcase()返回的引用已经指向了一个新的对象,而原本的q则还在原地
2. 重载“+” 和StringBuilder
重载的意思是,一个操作符在引用于特定的类时,被赋予了特殊的意义(用于String的“+”与“+=”是Java中仅有的两个重载过的操作符,而Java并不允许成员重载任何操作符)
操作符“+”可以用来连接String:
public class Contatenation {
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" + 47;
System.out.println(s);
}
}
public class UsingStringBuilder {
public static Random rand = new Random(47);
public String toString(){
StringBuilder result = new StringBuilder("[");
for(int i = 0; i < 25;i++){
result.append(rand.nextInt(100));
result.append(", ");
}
result.delete(result.length()-2,result.length());
result.append("]");
return result.toString();
}
public static void main(String[] args) {
UsingStringBuilder usb = new UsingStringBuilder();
System.out.println(usb);
}
}
StringBuilder提供了丰富而全面的方法,包括insert()、replace()、substring()甚至reverse(),但最常用的还是append()和toString()。还有delete()方法。
3.格式化输出
JavaSE5引入的format方法可用于PrintStream或PrintWriter对象,其中也包括System.out对象。
public class SimpleFormat {
public static void main(String[] args) {
int x = 5;
double y = 5.332542;
System.out.println("Row 1: [ " + x + " " + y + "]");
System.out.format("Row 1: [%d %f]\n" ,x,y);
System.out.printf("Row 1: [%d %f]\n" ,x,y);
}
}
format()与printf()是等价的,它们只需要一个简单的格式化字符串,加上一串参数即可,每个参数对应一个格式化修饰符
在Java中,所有新的格式化功能都由java.util.Formatter 类处理。可以将Formatter看作一个翻译器,它将你的格式化字符串与数据翻译称需要的结果,当你创建一个Formatter对象的时候,需要向其构造器传递一些信息,告诉它最终的结果将向哪里输出
public class Turtle {
private String name;
private Formatter f;
public Turtle(String name,Formatter f){
this.name = name;
this.f = f;
}
public void move(int x,int y){
f.format("%s The Turtle is at (%d,%d)\n",name,x,y);
}
public static void main(String[] args) {
PrintStream outAlias = System.out;
Turtle tommy = new Turtle("Tommy",new Formatter(System.out));
Turtle terry = new Turtle("terry",new Formatter(outAlias));
tommy.move(0,0);
tommy.move(3,4);
tommy.move(3,3);
terry.move(4,8);
terry.move(2,5);
terry.move(3,3);
}
}
4. 扫描输入
从文本或标准输入读取数据还是一件相当痛苦的事情。一般的解决之道就是读入一行文本,对其进行分词,然后使用Integer、Double等类的各种解析方法来解析数据
public class SimpleRead {
public static BufferedReader input = new BufferedReader(new StringReader("Sir Robin of Camelot\n 22 1.61803"));
public static void main(String[] args) {
try {
System.out.println("What is your name?");
String name = input.readLine();
System.out.println(name);
System.out.println("How old are you ? what is your favorite double?");
System.out.println("(input:<age> <double>");
String numbers = input.readLine();
System.out.println(numbers);
String[] numArray = numbers.split(" ");
int age = Integer.parseInt(numArray[0]);
double favorite = Double.parseDouble(numArray[1]);
System.out.format("Hi %s.\n",name);
System.out.format("In 5 years you will be %d.\n",age+5);
System.out.format("My favorite double is %f.",favorite/2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Scanner的构造器可以接受任何类型的输入对象,包括File对象、InputStream、String或者下面例子中的Readable对象。
public class BetterRead {
public static void main(String[] args) {
Scanner stdin = new Scanner(SimpleRead.input);
System.out.println("What is your name?");
String name = stdin.nextLine();
System.out.println(name);
System.out.println("How old are you ? what is your favorite double?");
System.out.println("(input:<age> <double>");
int age = stdin.nextInt();
double favorite = stdin.nextDouble();
System.out.println(age);
System.out.println(favorite);
System.out.format("Hi %s.\n",name);
System.out.format("In 5 years you will be %d.\n",age+5);
System.out.format("My favorite double is %f.",favorite/2);
}
}
网友评论