[英]How do I easily and neatly print multiple objects using a toString method, that are also aligned?
我有一個成員的ArrayList,每個都有自己的信息,包括姓名,年齡,出生日期等,當打印到終端時用toString方法調用。
這是代碼:
@Override
public String toString() {
return "|ID: " + id + "| Name: " + name + "| Age: " +
calculateAge(age, LocalDate.now()) + "| Tlf.: " + tlfNo + "| Active: " +
activeMember + "| Next payment: " + nextPayment + "|";
}
這是輸出:
|ID: 12| Name: Casper| Age: 49| Tlf.: 12345678| Active: true| Next payment: 2018-02-12|
|ID: 13| Name: Allan| Age: 69| Tlf.: 12345678| Active: true| Next payment: 2018-01-12|
|ID: 16| Name: Christina| Age: 100| Tlf.: 12345678| Active: false| Next payment: 2018-02-04|
|ID: 19| Name: RICK| Age: 49| Tlf.: 12345678| Active: false| Next payment: 2018-04-14|
如何讓不同的信息彼此對齊?
你可以這樣做:
public String toString() {
return String.format("|id: %10d |Name: %30s| Age: %02d | Tlf.: %d| Active: %s| Next Payment: %s |", id, getNameTrimmed() , age , tlfNo , activeMember, nextPayment );
}
private String getNameTrimmed(){
if(name.length()>30) {
return name.substring(0,27)+"...";
}
return name;
}
這樣,id將有10個字符(如果你有更長的ID,它仍然會破壞格式)名稱將有30,所以你需要添加一個方法給你30個字符名稱
你可以為它創建一個方法,因為toString
簡單,不起作用:
static String printPojos(Pojo... pojos) {
int maxName = Arrays.stream(pojos)
.map(Pojo::getName)
.mapToInt(String::length)
.max()
.orElse(0);
int maxId = Arrays.stream(pojos)
.mapToInt(x -> x.getName().length())
.max()
.orElse(0);
StringJoiner result = new StringJoiner("\n");
for (Pojo pojo : pojos) {
StringJoiner sj = new StringJoiner("|");
sj.add("ID: " + Strings.padEnd(Integer.toString(pojo.getId()), maxId, ' '));
sj.add(" Name: " + Strings.padEnd(pojo.getName(), maxName, ' '));
sj.add(" Age: " + Strings.padEnd(Integer.toString(pojo.getAge()), 3, ' '));
sj.add(" Active: " + Strings.padEnd(Boolean.toString(pojo.isActive()), 5, ' '));
result.merge(sj);
}
return result.toString();
}
我正在使用Strings::padEnd
(來自guava
,但即使沒有外部庫,這也很容易編寫)。
在我的情況下Pojo
看起來像這樣:
static class Pojo {
private final int id;
private final String name;
private final int age;
private final boolean active;
// constructor, getters
}
結果如下:
Pojo one = new Pojo("Casper", 49, true, 1);
Pojo two = new Pojo("Allan", 100, true, 10_000);
System.out.println(printPojos(one, two));
ID: 1 | Name: Casper| Age: 49 | Active: true
ID: 10000| Name: Allan | Age: 100| Active: true
我有一個簡單的問題實現,不需要外部庫。 如果你想使用外部庫,那么Apache-commons或Guava中有足夠的方法可用。 它可能會更聰明地完成,但這將成功:
class Member {
String id;
String name;
int age;
LocalDate date;
int tlfNo;
boolean activeMember;
LocalDate nextPayment;
public Member(String id, String name, int age, int tlfNo, boolean activeMember, LocalDate nextPayment) {
this.id = id;
this.name = name;
this.age = age;
this.tlfNo = tlfNo;
this.activeMember = activeMember;
this.nextPayment = nextPayment;
}
@Override
public String toString() {
return String.format("|ID: %s| Name: %s| Age: %s| Tlf.: %s| Active: %s| Next payment: %s|",
doFormat(id, "id", 10), doFormat(name, "name", 10),
doFormat(String.valueOf(age), "age", 10),
doFormat(String.valueOf(tlfNo), "tlfNo", 10),
doFormat(String.valueOf(activeMember), "active", 10),
doFormat(nextPayment.toString(), "nextPayment", 20));
}
String doFormat(String value, String fieldName, int maxLenght) {
if (value.length() > maxLenght) {
throw new IllegalArgumentException(String.format("cannot format string longer than %s for %s, value = %s", maxLenght, fieldName, value));
}
return padLeftSpaces(value, maxLenght);
}
public String padtLefSpaces(String inputString, int length) {
if (inputString.length() >= length) {
return inputString;
}
StringBuilder sb = new StringBuilder();
while (sb.length() < length - inputString.length()) {
sb.append(' ');
}
sb.append(inputString);
return sb.toString();
}
}
我們的想法是用空格填充所有字段,只替換占用的空間。 pad left方法是從bealdung借來的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.