Printing out a table in console This program prints out a table in the console. Suggestions for improvements are welcome.

Example output

Name             Sex      Age
Klaus Ulbrecht   male     12
Dieter           male     14
Ursula           female   16


You can test and modify the program here.

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;

class Main {
  private static List&lt;List&lt;String&gt;&gt; table; 

  public static void main(String[] args) {
    initTable();
    int spacing = 3;
    printTable(spacing);
  }

  private static void initTable() {
    List&lt;String&gt; row1 = Arrays.asList("Name", "Klaus Ulbrecht", "Dieter", "Ursula");
    List&lt;String&gt; row2 = Arrays.asList("Sex", "male", "male", "female");
    List&lt;String&gt; row3 = Arrays.asList("Age", "12", "14", "16");
    table = Arrays.asList(row1, row2, row3);
  }

  private static void printTable(int spacing) {
    List&lt;Integer&gt; maxLengths = findMaxLengths();

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i &lt; table.get(0).size(); i++) {
      for (int j = 0; j &lt; table.size(); j++) {
        String currentValue = table.get(j).get(i);
        sb.append(currentValue);
        for (int k = 0; k &lt; (maxLengths.get(j) - currentValue.length() + spacing); k++) {
          sb.append(' ');
        }
      }
      sb.append('\n');
    }

    System.out.println(sb);
  }

  private static List&lt;Integer&gt; findMaxLengths() {
    List&lt;Integer&gt; maxLengths = new ArrayList&lt;&gt;();
    for (List&lt;String&gt; row : table) {
      int maxLength = 0;
      for (String value : row) {
        if (value.length() &gt; maxLength) {
          maxLength = value.length();
        }
      }
      maxLengths.add(maxLength);
    }
    return maxLengths;
  }
}
Hello and thank your for your code. I dont' know what kind of improvements you want but from an Object Oriented perspective I see some improvements.

The first one is to get rid of all the static methods and fields. You can easily move all your methods to an AsciiTable class with a print(OutputStream out):void method.

You can also use arrays instead of list and split the single argument to one for the columns titles and another for the content. This will clarify the initiliazation of your table.

Table table = new Table(
    new String[]{"Name", "Sex", "Age"},
    new Object[][]{
            {"Klaus Ulbrecht", "male", 12},
            {"Dieter", "male", 14},
            {"Ursula", "female", 16}
        });


As you can see I changed the order so that the cognitive load is reduced, by 
looking at the declaration we alrdeay have an idea of what are the titles and the content. We read for top to bottom, so it is more easier to have a declaration that already looks like that. This avoid your brain to switch the representation.

Another improvement that you can do is apply the separation of concerns principle by moving the "printing" away of the table. This is done easily with the builder where your Table is a director that drive a Format.

With this pattern you should be able to add another representation without changing the Table.

interface Format {
    void startHeader();
    void endHeader();

    void startBody();
    void endBody();

    void startRow();
    void endRow();

    void addColumn(Object value);
}

Format console = new Ascii(System.out, "   "); 
table.writeTo(console);


Now that your model (Table) is separated from the view (Format) you may discover that the model is quite simple and exists mainly to drive the view as the director in the builder pattern. But you can add new methods to filter or sort your table.

Table table = new Table(
    new String[]{"Name", "Sex", "Age"},
    new Object[][]{
            {"Klaus Ulbrecht", "male", 12},
            {"Dieter", "male", 14},
            {"Ursula", "female", 16}
    });
table.filter(1, "male"::equalsIgnoreCase)
     .sort(2, Comparator.naturalOrder())
     .writeTo(console);

Name             Sex    Age   
Klaus Ulbrecht   male   12    
Dieter           male   14          


If you don't want to migrate to the object oriented way you can still improve the robustness of your code by dealing with empty columns or rows.

[1] Single Responsibility Priniciple is part of the S.O.L.I.D. acronym. https://en.wikipedia.org/wiki/SOLID

[2] When I speak about the builder pattern I refer to the creational pattern. Not the "fluent way of writing". https://en.wikipedia.org/wiki/Builder_pattern