zoukankan      html  css  js  c++  java
  • 字符串

    字符串的常用性应该属于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 + "
    "
        } 
        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() + "
    ";
        }
        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! 
    */
    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    Traceroute侦测主机到目的主机之间所经路由情况的重要工具
    TCP/IP详解之IP协议
    Hello world
    [LeetCode] 198. 打家劫舍
    [LeetCode] 191. 位1的个数
    [LeetCode] 190. 颠倒二进制位
    python里的排序
    [LeetCode] 189. 旋转数组
    [LeetCode]187. 重复的DNA序列
    [LeetCode] 179. 最大数
  • 原文地址:https://www.cnblogs.com/CherryTab/p/11985988.html
Copyright © 2011-2022 走看看