1. 程式人生 > 程式設計 >淺談Java8對字串連線的改進正確姿勢

淺談Java8對字串連線的改進正確姿勢

我們提出一個需求:有一個 List<String>,將其格式化為 元素1,元素2,元素3,... 元素N 的字串形式。

毋庸置疑, Java8 之前我們的第一反應是使用 StringBuilder

public static String formatList(List<String> list,String delimiter) {
 StringBuilder result = new StringBuilder();
 for (String str : list) {
  result.append(str).append(delimiter);
 }
 // 刪除末尾多餘的 delimiter
 result.delete(result.length() - delimiter.length(),result.length()); 
 
 return result.toString();
}

public static void main(String[] args) throws Exception {
 List<String> list = Arrays.asList("a","b","c","d","e","f","g");

 System.out.println("使用 StringBuilder:");
 String format = formatList(list,",");
 System.out.println(format);
}

執行結果:

JDK1.8 時,添加了一個新的用於字串連線的類,專門用於這種需要 分隔符 的場合,它就是 StringJoinerStringJoiner 在構造時可以指定一個分隔符(delimiter),然後每連線一個元素它便會加上一個 delimiter ,使用 StringJoiner 改寫 formatList

public static String formatList(List<String> list,String delimiter) {
 StringJoiner result = new StringJoiner(delimiter);
 for (String str : list) {
  result.add(str);
 }
 return result.toString();
}

public static void main(String[] args) throws Exception {
 List<String> list = Arrays.asList("a","g");

 System.out.println("使用 StringJoiner:");
 String format = formatList(list,");
 System.out.println(format);
}

執行結果:

formatList 的程式碼更加的簡潔了 —— 當然我們還可以更簡潔 —— JDK1.8 為 String 類添加了一個新的靜態方法, String.join

可以看到,第一個引數為一個分隔符 delimiter ,第二個引數可以是一個 Iterable ,或者是一個變長引數的 CharSequenceString 就是 CharSequence 的子類)。 所以 formatList 方法只需要一句程式碼就搞定:

public static String formatList(List<String> list,String delimiter) {
 return String.join(delimiter,list);
}

當然,我們能猜到, String.join 方法的功能內部是通過 StringJoiner 來實現的, String.join (CharSequence,Iterable) 的原始碼:

但是我們看到了 String.join 方法的不足 —— 它不能指定字首和字尾 —— 比如我們如果想要直接將 List<String> 格式化為 { 元素1,... 元素N } 呢?(此時字首為 "{ " ,字尾為 " }"

檢視 StringJoiner 的構造方法,發現 StringJoiner 除了指定 分隔符 的構造方法,還有一個可以指定 分隔符、字首和字尾 的構造方法:

修改 formatList

public static String formatList(
  List<String> list,String delimiter,String prefix,String suffix) {

 StringJoiner result = new StringJoiner(delimiter,prefix,suffix);
 for (String str : list) {
  result.add(str);
 }
 return result.toString();
}

public static void main(String[] args) throws Exception {
 List<String> list = Arrays.asList("a","g");

 System.out.println("使用 StringJoiner,帶字首和字尾:");
 String format = formatList(list,"{ "," }");
 System.out.println(format);
}

執行結果:

很棒~ 但能不能更簡潔呢? 事實上, Java8 對於字串集合的連線操作提供了一個專門的流式 API,即 Collectors.joining

函式:!

無參的 joining() 方法,即不存在連線符(底層實現為 StringBuilder);

joining(CharSequence delimiter) 方法,即分隔符為 delimiter(底層實現為 StringJoiner);j

oining(CharSequence delimiter,CharSequence prefix,CharSequence suffix)方法,即分隔符為 delimiter,字首為 prefix,字尾為 suffix(底層實現為 StringJoiner)。

那怎麼使用呢? 我們直接使用三個引數的 Collectors.joining 方法改寫 formatList:

public static String formatList(
  List<String> list,String suffix) {

 return list.stream().collect(Collectors.joining(delimiter,suffix));
}

public static void main(String[] args) throws Exception {
 List<String> list = Arrays.asList("a","g");

 System.out.println("使用 Collectors.joining:");
 String format = formatList(list," }");
 System.out.println(format);
}

執行結果:

檢視 StringJoiner 的原始碼,我們可以知道 StringJoiner 的底層實現就是 StringBuilder —— Java8 將 使用分隔符連線多個字串 這一功能進行封裝,提供這麼多易用且簡介的 API,確實在很大程度上方便了編碼。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。