与StringBuilder很好看的表 [英] Nice looking table with StringBuilder

查看:67
本文介绍了与StringBuilder很好看的表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I know that "printf" method can use string formatting.

我的问题是:
有没有办法用StringBuilder创建漂亮的表格class?

My question is : Is there a way to create a nice looking table with StringBuilder class?

例如:

| Id | Category | Level | Space |类型|地址|维度|限制|

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

And under that row, i must add the values of each columns!

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

Doing something like that : example but with StringBuilder

所以社区希望看到我的答案(我不明白为什么...但是我会把它放在任何方式!)

So the community want to see my answer (which i don't understand why ... but any way i will put it !)

public String toString(){
    StringBuilder s = new StringBuilder();

    s.append("Category: "+this.category+"\t");
    s.append("Level: "+this.level.toString()+"\t");

    return s.toString();
}

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

Now explain me, why seeing my answer will help me ? I really want to see your answer !

推荐答案

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

A simple approach is, of course, to create hard-wired printf statements. However, this is not very flexible, because you always have to fix the column widths, and the functions will always be specific for one class and its fields.

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

So I'd like to propose a helper class that mainly does two things:


  • 封装表格单元格条目的创建(通过Java 8 函数

  • 计算给定元素集的每个列的最大宽度。

假设有一个给定的模型类,例如 Person ,例如:

Let there be a given model class, like a Person, for example:

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

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

Then, I'd like to create a "nice" table as follows:

TableStringBuilder<Person> t = new TableStringBuilder<Person>();
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);

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

And I'd expect the contents of this string to be a nicely formatted table:

   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 及其应用程序:

Here is a MVCE that shows such a TableStringBuilder and its application:

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<Person> persons = new ArrayList<Person>();
        for (int i=0; i<10; i++)
        {
            persons.add(new Person());
        }

        TableStringBuilder<Person> t = new TableStringBuilder<Person>();
        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<T>
{
    private final List<String> columnNames;
    private final List<Function<? super T, String>> stringFunctions;

    TableStringBuilder()
    {
        columnNames = new ArrayList<String>();
        stringFunctions = new ArrayList<Function<? super T, String>>();
    }

    void addColumn(String columnName, Function<? super T, ?> fieldFunction)
    {
        columnNames.add(columnName);
        stringFunctions.add((p) -> (String.valueOf(fieldFunction.apply(p))));
    }

    private int computeMaxWidth(int column, Iterable<? extends T> elements)
    {
        int n = columnNames.get(column).length();
        Function<? super T, String> 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<Integer> computeColumnWidths(Iterable<? extends T> elements)
    {
        List<Integer> columnWidths = new ArrayList<Integer>();
        for (int c=0; c<columnNames.size(); c++)
        {
            int maxWidth = computeMaxWidth(c, elements);
            columnWidths.add(maxWidth);
        }
        return columnWidths;
    }

    public String createString(Iterable<? extends T> elements)
    {
        List<Integer> columnWidths = computeColumnWidths(elements);

        StringBuilder sb = new StringBuilder();
        for (int c=0; c<columnNames.size(); c++)
        {
            if (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<columnNames.size(); c++)
        {
            if (c > 0)
            {
                sb.append("+");
            }
            sb.append(padLeft("", '-', columnWidths.get(c)));
        }
        sb.append("\n");

        for (T element : elements)
        {
            for (int c=0; c<columnNames.size(); c++)
            {
                if (c > 0)
                {
                    sb.append("|");
                }
                String format = "%"+columnWidths.get(c)+"s";
                Function<? super T, String> 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<length; i++)
        {
            char c = (char)(random.nextInt(26) + offset);
            sb.append(c);
            offset = 'a';
        }
        return sb.toString();
    }

    int getId()
    {
        return id;
    }

    String getFirstName()
    {
        return firstName;
    }

    String getLastName()
    {
        return lastName;
    }

    float getHeight()
    {
        return height;
    }
}

这篇关于与StringBuilder很好看的表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆