Java 的格式化輸出

package io;

import java.util.GregorianCalendar;
import java.util.TimeZone;
/**
 * Java 的格式化輸出
 * Java 的格式化輸出一般用於下面幾種情況
 * (1)String.format(String formatter,agr...)
 * (2)System.out.printf(String formatter,agr...) 
 * (3)PrintWriter.printf(String formatter,agr...) 
 * 上面三種典型用法中,都是根據一個字符串格式的formatter和一個參數列表,獲得一個格式化的字符串.
 * 其功能類似於c語言中的pringf函數.
 * 參數formatter有固定的語法,主要語法有下面三種:
 * 
 * (1)常規類型、字符類型和數值類型的格式說明符的語法如下: 
 * 
 * %[argument_index$][flags][width][.precision]conversion
 * 
 * %: 這個是參數轉換格式化串的起點
 * argument_index$: 由argument_index和$構成,表示使用後面參數列表中第argument_index參數來獲取格式化字符
 * flags: 是一些標誌,比如 - 可以將參數左對齊,這個根據後面參數的具體類型有不同的標誌可選用
 * width: 表示將後面參數格式化後的寬度,比如寬度爲3,並使用-作爲flag後,格式化整數5後,得到的字符串爲"5  ",即5後面加2空格
 * .precision: 表示精度,這個一般針對浮點數,比如3.1415929 使用"%.2f"格式化之後得到3.14
 * conversion:是格式化規則,比如上面的"%.2f"中的f就是一個規則,f只能對應浮點型參數,否則會拋異常
 * conversion也是參數格式化串的終點
 * 
 * 上面format(String formatter,agr...)中的formatter可以包含很多的參數格式化串,
 * 也可以包含非格式化串,這些非格式化串字符將按照原樣輸出.
 * 
 * 比如調用format("小明今年 %2$-3d歲,生於 %1$-5d年.",1994,20)
 * 得到的格式化之後的字符串爲:小明今年 20 歲,生於 1994 年.
 * 注意,上面的formatter中包含兩個格式化串:%2$-3d 和 %1$-5d,都是以%開頭,d(conversion)結尾的.
 * 其他部分,是非格式化串字符,比如"小明今年 "則按原樣輸出.
 * %2$-3d中的2$表示使用後面的第二個參數,也就是20.注意這裏20是2個寬度,而-3表示格式化成3個寬度並且左對齊,
 * 這樣得到的輸出就是"20 歲",20和歲之間加了一個空格,以是的20格式化之後的寬度變成3.
 * 
 * (2)用來表示日期和時間類型的格式說明符的語法如下: 
 * 
 *  %[argument_index$][flags][width]conversion
 *  
 *  這個跟上面的有兩點區別:首先,格式化時間不需要[.precision]這個了;
 *  其次,格式化時間的conversion 有特殊要求,即,必須要在前面加一個t或T.
 *  有一些專門的conversion用於格式化時間,使用這些conversion時,需要在前面加一個t
 *  
 *  比如,
 *  Calendar c = new GregorianCalendar(1984, 6, 4);
 *  String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
 *  這裏%1$tm中的m是conversion,表示輸出兩位數月份,t是前綴.
 *  格式化之後得到:Duke's Birthday: 07 4,1984
 *  
 *  (3)與參數不對應的格式說明符的語法如下: 
 *  
 *  %[flags][width]conversion
 *  
 *  這個與前面(1)的區別是去掉了[argument_index$]和[.precision]表示:
 *  首先,不能指定參數位置與格式化串的對應關係,則使用格式化串的位置尋找後面對應位置的參數
 *  format("小明今年 %-3d歲,生於 %-5d年.",1994,20)
 *  上面的格式化串%-3d位置爲1,則使用第一個參數1994來獲取格式化串,
 *  最終返回"小明今年 1994歲,生於 20   年." 這樣就不對了.
 *  所以,後面的參數位置要和前面的格式化串對應.改成:
 *  format("小明今年 %-3d歲,生於 %-5d年.",20,1994)
 *  
 *
 */

public class TestStringFormat
{
  public static void main(String[] args)
  {
    //格式化輸出整數
    String str1 = String.format("小明今年 %2$-3d歲,生於 %1$-5d年.",1994,20);
    System.out.println(str1);
    //輸出:小明今年 20 歲,生於 1994 年.
    
    //沒有參數對應時,要讓格式化串和參數的順序對應好
    str1 = String.format("小明今年 %-3d歲,生於 %-5d年.",20,1994,20);
    System.out.println(str1);
    //輸出:小明今年 20 歲,生於 1994 年.
    
    //沒有參數對應時,參數數量少於格式化串數量時,格式化串變成空,
    //參數多了則沒關係(參考上面的20,1994,20三個參數只用到了兩個)
    
    //有參數對應時,如果用3$指定了第三個參數,而參數列表中只有2個參數則會報錯
    //str1 = String.format("小明今年 %2$-3d歲,生於 %1$-5d年.",1994);//這樣的報錯
    
    //格式化日期,時間
    GregorianCalendar c = new GregorianCalendar(1984, 6, 4,12,22,33);//構造制定日期時間的日曆
    c.setTimeZone(TimeZone.getTimeZone("GMT+8"));
    c.setTimeInMillis(System.currentTimeMillis());//設置爲當前日期時間
    
    str1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
    System.out.println(str1);//輸出:Duke's Birthday: 02 27,2014
    
    str1 = String.format("Time: %1$tH:%1$tM:%1$tS",c);
    System.out.println(str1);//輸出: Time: 20:19:09
    
    //格式化浮點數,如果浮點數格式化後小數位數小於原來的值,則是按照四捨五入方式 捨棄的
    str1 = String.format("π值爲 %1$s,浮點數爲:%1$f,精確到3位小數爲:%1$.3f", 3.1415926);
    System.out.println(str1);//輸出:π值爲 3.1415926,浮點數爲:3.141593,精確到3位小數爲:3.142
    
    //格式化輸出數組,左對齊,每個整數佔5個寬度
    int[][] dataArr = {{1,2,3},{4,5,6}};
    for(int i=0;i<2;i++)
    {
      for(int j=0;j<3;j++)
      {
        System.out.printf("%-5d",dataArr[i][j]);
      }
      System.out.println("");
    }
    /*
     * 輸出:
     * 1    2    3    
     * 4    5    6    
     */
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章