与StringBuilder很好看的表

我知道“printf”方法可以使用字符串格式。

我的问题是:有没有办法用StringBuilder类创建一个漂亮的表?

例如:

|Id|Category|Level|Space|Type|Adress|Dimension|Limits|

在那一行下,我必须添加每列的值!

做类似的事情: 示例,但使用StringBuilder


所以社区希望看到我的答案(我不明白为什么……但是我会把它放在哪里!)

 public String toString(){ StringBuilder s = new StringBuilder(); s.append("Category: "+this.category+"\t"); s.append("Level: "+this.level.toString()+"\t"); return s.toString(); } 

现在解释一下,为什么看到我的答案对我有帮助? 我真的很想看到你的答案!

当然,一种简单的方法是创建硬连线的printf语句。 但是,这不是很灵活,因为您始终必须修复列宽,并且函数将始终特定于一个类及其字段。

所以我想提出一个主要做两件事的辅助类:

  • 封装表格单元格条目的创建(通过Java 8 Function
  • 计算给定元素集的每个列的最大宽度。

让一个给定的模型类,比如Person ,例如:

 class Person { int getId() { ... } String getFirstName() { ... } String getLastName() { ... } float getHeight() { ... } } 

然后,我想创建一个“漂亮”的表如下:

 TableStringBuilder t = new TableStringBuilder(); t.addColumn("id", Person::getId); t.addColumn("first name", Person::getFirstName); t.addColumn("last name", Person::getLastName); t.addColumn("height", Person::getHeight); String s = t.createString(persons); 

我希望这个字符串的内容是一个格式很好的表:

  id| first name| last name|height -----+-------------+-------------+------ 41360|Xvnjhpdqdxvcr| Stvybcwvm| 1.7 3503| Krxvzxk| Xtspsjd| 1.6 41198| Uegqfl| Qlocfljbepo| 1.58 26517| Somyar| Aopufo| 1.77 13773| Dxehxjbhwgsm| Jgnlonjv| 1.77 13067| Zozitk| Jbozwd| 1.81 46534| Bosyq| Kcprrdc| 1.55 93862| Rlfxblgqp| Pgrntaqoos| 1.85 12155| Kjpjlavsqc|Rxfrrollhwhoh| 1.79 75712| Fwpnd| Mwcsshwx| 1.78 

这是一个MVCE ,它显示了这样一个TableStringBuilder及其应用程序:

 import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.function.Function; public class TableStringTest { public static void main(String[] args) { List persons = new ArrayList(); for (int i=0; i<10; i++) { persons.add(new Person()); } TableStringBuilder t = new TableStringBuilder(); t.addColumn("id", Person::getId); t.addColumn("first name", Person::getFirstName); t.addColumn("last name", Person::getLastName); t.addColumn("height", Person::getHeight); String s = t.createString(persons); System.out.println(s); } } class TableStringBuilder { private final List columnNames; private final List> stringFunctions; TableStringBuilder() { columnNames = new ArrayList(); stringFunctions = new ArrayList>(); } void addColumn(String columnName, Function fieldFunction) { columnNames.add(columnName); stringFunctions.add((p) -> (String.valueOf(fieldFunction.apply(p)))); } private int computeMaxWidth(int column, Iterable elements) { int n = columnNames.get(column).length(); Function f = stringFunctions.get(column); for (T element : elements) { String s = f.apply(element); n = Math.max(n, s.length()); } return n; } private static String padLeft(String s, char c, int length) { while (s.length() < length) { s = c + s; } return s; } private List computeColumnWidths(Iterable elements) { List columnWidths = new ArrayList(); for (int c=0; c elements) { List columnWidths = computeColumnWidths(elements); StringBuilder sb = new StringBuilder(); for (int c=0; c 0) { sb.append("|"); } String format = "%"+columnWidths.get(c)+"s"; sb.append(String.format(format, columnNames.get(c))); } sb.append("\n"); for (int c=0; c 0) { sb.append("+"); } sb.append(padLeft("", '-', columnWidths.get(c))); } sb.append("\n"); for (T element : elements) { for (int c=0; c 0) { sb.append("|"); } String format = "%"+columnWidths.get(c)+"s"; Function f = stringFunctions.get(c); String s = f.apply(element); sb.append(String.format(format, s)); } sb.append("\n"); } return sb.toString(); } } //Dummy Person Class class Person { private int id; private String firstName; private String lastName; private float height; private static Random random = new Random(0); Person() { id = random.nextInt(100000); firstName = createRandomString(); lastName = createRandomString(); height = (150 + random.nextInt(40)) / 100.0f; } private static String createRandomString() { int length = random.nextInt(10) + 5; StringBuilder sb = new StringBuilder(); char offset = 'A'; for (int i=0; i 

好的,非常感谢所有对我好的答案。

我发现我们可以这样做:

 public String toString(){ StringBuilder s = new StringBuilder(); s.append(String.format("%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n","Identifier","Category","Level","Space","Type","Dimension","Limits")); s.append(String.format("=============================================================================================================================================\n")); for(String id : this.idTable.keySet()) { s.append(String.format("%-20s",id)); s.append(this.idTable.get(id).toString()); //s.append("Identifier: " +id+" "+this.idTable.get(id).toString()+"\n"); } return s.toString(); } 

请注意, String.format执行我想要的所有工作,之前不知道!

Regardind给你@ Marco13,你做得很好!!!! 谢谢大家!

PS:我会接受来自@ Marco13的消息,因为他的实施也非常好!