咱們提出一個需求:有一個 List<String>
,將其格式化爲 元素1, 元素2, 元素3, ... 元素N 的字符串形式。app
毋庸置疑,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); }
運行結果:
ui
JDK1.8 時,添加了一個新的用於字符串鏈接的類,專門用於這種須要 分隔符 的場合,它就是 StringJoiner
。StringJoiner
在構造時能夠指定一個分隔符(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", "b", "c", "d", "e", "f", "g"); System.out.println("使用 StringJoiner:"); String format = formatList(list, ", "); System.out.println(format); }
運行結果:
spa
formatList
的代碼更加的簡潔了 —— 固然咱們還能夠更簡潔 —— JDK1.8 爲 String
類添加了一個新的靜態方法,String.join
:
code
能夠看到,第一個參數爲一個分隔符 delimiter,第二個參數能夠是一個 Iterable
,或者是一個變長參數的 CharSequence
(String
就是 CharSequence
的子類)。
因此 formatList
方法只須要一句代碼就搞定:orm
public static String formatList(List<String> list, String delimiter) { return String.join(delimiter, list); }
固然,咱們能猜到,String.join
方法的功能內部是經過 StringJoiner
來實現的,String.join (CharSequence, Iterable)
的源碼:blog
可是咱們看到了 String.join
方法的不足 —— 它不能指定前綴和後綴 —— 好比咱們若是想要直接將 List<String>
格式化爲 { 元素1, 元素2, 元素3, ... 元素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", "b", "c", "d", "e", "f", "g"); System.out.println("使用 StringJoiner,帶前綴和後綴:"); String format = formatList(list, ", ", "{ ", " }"); System.out.println(format); }
運行結果:
很棒~ 但能不能更簡潔呢? 事實上,Java8 對於字符串集合的鏈接操做提供了一個專門的流式 API,即 Collectors.joining
函數:
joining()
方法,即不存在鏈接符(底層實現爲 StringBuilder
);joining(CharSequence delimiter)
方法,即分隔符爲 delimiter(底層實現爲 StringJoiner
);joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
方法,即分隔符爲 delimiter,前綴爲 prefix,後綴爲 suffix(底層實現爲 StringJoiner
)。那怎麼使用呢? 咱們直接使用三個參數的 Collectors.joining
方法改寫 formatList
:
public static String formatList( List<String> list, String delimiter, String prefix, String suffix) { return list.stream().collect(Collectors.joining(delimiter, prefix, suffix)); } public static void main(String[] args) throws Exception { List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g"); System.out.println("使用 Collectors.joining:"); String format = formatList(list, ", ", "{ ", " }"); System.out.println(format); }
運行結果:
查看 StringJoiner
的源碼,咱們能夠知道 StringJoiner
的底層實現就是 StringBuilder
—— Java8 將 使用分隔符鏈接多個字符串 這一功能進行封裝,提供這麼多易用且簡介的 API,確實在很大程度上方便了編碼。