字符串

字符串的常用性应该属于top3

 

// strings/Concatenation.java

public class Concatenation {
    public static void main(String[] args) { 
        String mango = "mango"; 
        String s = "abc" + mango + "def" + 47; 
        System.out.println(s);
    } 
}
/* Output:
abcmangodef47 
*/
public static void main(java.lang.String[]); 
 Code:
  Stack=2, Locals=3, Args_size=1
  0: ldc #2; //String mango 
  2: astore_1 
  3: new #3; //class StringBuilder 
  6: dup 
  7: invokespecial #4; //StringBuilder."<init>":() 
  10: ldc #5; //String abc 
  12: invokevirtual #6; //StringBuilder.append:(String) 
  15: aload_1 
  16: invokevirtual #6; //StringBuilder.append:(String) 
  19: ldc #7; //String def 
  21: invokevirtual #6; //StringBuilder.append:(String) 
  24: bipush 47 
  26: invokevirtual #8; //StringBuilder.append:(I) 
  29: invokevirtual #9; //StringBuilder.toString:() 
  32: astore_2 
  33: getstatic #10; //Field System.out:PrintStream;
  36: aload_2 
  37: invokevirtual #11; //PrintStream.println:(String) 
  40: return

编译器自动引入了 java.lang.StringBuilder 类。虽然源代码中并没有使用 StringBuilder 类,但是编译器却自作主张地使用了它,就因为它更高效。

 

// strings/WhitherStringBuilder.java

public class WhitherStringBuilder { 
    public String implicit(String[] fields) { 
        String result = ""; 
        for(String field : fields) { 
            result += field;
        }
        return result; 
    }
    public String explicit(String[] fields) { 
        StringBuilder result = new StringBuilder(); 
        for(String field : fields) { 
            result.append(field); 
        } 
        return result.toString(); 
    }
}

implicit

public java.lang.String implicit(java.lang.String[]); 
0: ldc #2 // String 
2: astore_2
3: aload_1 
4: astore_3 
5: aload_3 
6: arraylength 
7: istore 4 
9: iconst_0 
10: istore 5 
12: iload 5 
14: iload 4 
16: if_icmpge 51 
19: aload_3 
20: iload 5 
22: aaload 
23: astore 6 
25: new #3 // StringBuilder 
28: dup 
29: invokespecial #4 // StringBuilder."<init>"
32: aload_2 
33: invokevirtual #5 // StringBuilder.append:(String) 
36: aload 6 
38: invokevirtual #5 // StringBuilder.append:(String;) 
41: invokevirtual #6 // StringBuilder.toString:() 
44: astore_2 
45: iinc 5, 1 
48: goto 12 
51: aload_2 
52: areturn

可见在循环里新建了n次StringBuilder

explicit

public java.lang.String explicit(java.lang.String[]); 
0: new #3 // StringBuilder 
3: dup
4: invokespecial #4 // StringBuilder."<init>" 
7: astore_2 
8: aload_1 
9: astore_3 
10: aload_3 
11: arraylength 
12: istore 4 
14: iconst_0 
15: istore 5 
17: iload 5 
19: iload 4 
21: if_icmpge 43 
24: aload_3 
25: iload 5 
27: aaload 
28: astore 6 
30: aload_2 
31: aload 6 
33: invokevirtual #5 // StringBuilder.append:(String) 
36: pop
37: iinc 5, 1 
40: goto 17 
43: aload_2 
44: invokevirtual #6 // StringBuilder.toString:() 
47: areturn

只新建一次,这说明即使编译器足够聪明,但是也并非任何操作都能优化。

 

意外递归,不要使用this来打印地址

// strings/ArrayListDisplay.java 
import java.util.*;
import java.util.stream.*; 
import generics.coffee.*;
public class ArrayListDisplay { 
    public static void main(String[] args) {
        List<Coffee> coffees = 
            Stream.generate(new CoffeeSupplier())
                .limit(10)
                .collect(Collectors.toList()); 
        System.out.println(coffees); 
    } 
}
/* Output: 
[Americano 0, Latte 1, Americano 2, Mocha 3, Mocha 4, 
Breve 5, Americano 6, Latte 7, Cappuccino 8, Cappuccino 9] 
*/ 
// strings/InfiniteRecursion.java 
// Accidental recursion 
// {ThrowsException} 
// {VisuallyInspectOutput} Throws very long exception
import java.util.*;
import java.util.stream.*;

public class InfiniteRecursion { 
    @Override 
    public String toString() { 
        return " InfiniteRecursion address: " + this + "\n"
    } 
    public static void main(String[] args) { 
        Stream.generate(InfiniteRecursion::new) 
            .limit(10) 
            .forEach(System.out::println); 
    } 
} 

这里会报错,因为string + 会将后面的对象也转为string,然后就又跳到tostring方法,发生了递归死循环。

如果你真的想要打印对象的内存地址,应该调用 Object.toString() 方法,这才是负责此任务的方法。所以,不要使用 this,而是应该调用 super.toString() 方法。

public class InfiniteRecursion {
    @Override
    public String toString() {
        return " InfiniteRecursion address: " + super.toString() + "\n";
    }
    public static void main(String[] args) {
        Stream.generate(InfiniteRecursion::new)
                .limit(10)
                .forEach(System.out::println);
    }
}

 

一些通用的方法api自行查找

 

格式化输出

在 Java 中,所有的格式化功能都是由 java.util.Formatter 类处理的。可以将 Formatter 看做一个翻译器,它将你的格式化字符串与数据翻译成需要的结果。当你创建一个 Formatter 对象时,需要向其构造器传递一些信息,告诉它最终的结果将向哪里输出:

// strings/Turtle.java 
import java.io.*;
import java.util.*;

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);     
        terry.move(4,8);     
        tommy.move(3,4);     
        terry.move(2,5);     
        tommy.move(3,3);     
        terry.move(3,3);   
    } 
} 
/* Output: 
Tommy The Turtle is at (0,0) 
Terry The Turtle is at (4,8) 
Tommy The Turtle is at (3,4) 
Terry The Turtle is at (2,5) 
Tommy The Turtle is at (3,3) 
Terry The Turtle is at (3,3) 
*/

 

 

StringTo'kenizer类,分词用的,字符串的一大部分是正则的使用,这块我的智商较低,基本靠查。

// strings/ReplacingStringTokenizer.java 
import java.util.*; 

public class ReplacingStringTokenizer {   
    public static void main(String[] args) {     
        String input =       
          "But I'm not dead yet! I feel happy!";     
        StringTokenizer stoke = new StringTokenizer(input);     
        while(stoke.hasMoreElements())       
            System.out.print(stoke.nextToken() + " ");     
        System.out.println(); 
        System.out.println(Arrays.toString(input.split(" ")));     
        Scanner scanner = new Scanner(input);     
        while(scanner.hasNext())       
            System.out.print(scanner.next() + " ");   
    }
} 
/* Output: 
But I'm not dead yet! I feel happy! 
[But, I'm, not, dead, yet!, I, feel, happy!] 
But I'm not dead yet! I feel happy! 
*/
posted @ 2019-12-04 22:02  zhangyu63  阅读(142)  评论(0编辑  收藏  举报