[英]Customize the way TreeSet prints Map.Entry values
我有一個包含Map.Entry<String, Double>
值的TreeSet
,當我嘗試使用Iterator
迭代此結構並打印其鍵值對時,標准輸出如下所示:
Tolkien=40.25 JKRowling=35.5 OBowden=14.0
但是我想對輸出使用自定義格式 ,並將=
符號替換為->
例如:
Tolkien -> 40.25, JKRowling -> 35.5, OBowden -> 14.0
這是我現在的代碼:
Iterator iterator;.
iterator = lib.getSortedBooks().iterator();
while (iterator.hasNext()) {
System.out.printf(iterator.next() + " ");
}
正確格式化輸出的最佳方法是哪一種?
您可以通過簡單地將=
字符替換為->
字符來解決問題:
Iterator<Entry<String, Double>> iterator = lib.getSortedBooks().iterator();
while (iterator.hasNext()) {
Entry book = iterator.next();
String bookAsText = book.toString();
String adjustedText = bookAsText.replace("=", " -> ");
System.out.print(adjustedText + ", ");
}
請注意,您的輸出現在有一個尾隨,
最終。 您可以使用String#substring
方法將其刪除,或者在處理最后一個元素時不附加它(在iterator.hasNext()
前面查找一個元素),或者只使用StringJoiner
,我稍后將向您展示。
但是,如果您始終想要該顯式輸出,則不應依賴 toString
方法以其方式進行打印。 誰知道,這種情況將來可能會改變。
您應該顯式構建輸出。 有助於這是StringJoiner類,它可以讓你加入琴弦與添加像一個分隔符,
。 因此,使用如下代碼:
Set<Entry<String, Double>> books = lib.getSortedBooks();
String entryDelimiter = ", "
String valueDelimiter = " -> ";
StringJoiner sj = new StringJoiner(entryDelimiter);
for (Entry<String, Double> book : books) {
sj.add(book.getKey());
sj.add(valueDelimiter);
sj.add(book.getValue());
}
String output = sj.toString();
System.out.println(output);
或者使用Streams
的更緊湊的Java 8解決方案:
String output = lib.getSortedBooks().stream()
.map(book -> book.getKey() + " -> " + book.getValue())
.collect(Collectors.joining(", "));
System.out.println(output);
該方法將集合用作流的源。 然后,它首先將每個元素都轉移到book.getKey() + "->" + book.getValue()
,這就是Stream#map
作用。 之后,它將所有這些元素與結合在一起,
最后收集它們。
請注意,如果您不再需要對元素進行排序,也可以並行化它。 因此,只需在兩者之間調用Stream#parallel
。 它可以將給定的流“ 轉換 ”為並行流。
根據項目的大小,您應該考慮將書籍的表示形式從Map.Entry
更改為自己的類Book
例如:
public class Book() {
private final String mAuthor;
private final double mPrice;
public Book(final String author, final double price) {
this.mAuthor = author;
this.mPrice = price;
}
public String getAuthor() {
return this.mAuthor;
}
public double getPrice() {
return this.mPrice;
}
@Override
public String toString() {
return getAuthor + " -> " + getPrice();
}
}
這種方法對於將來的更改要靈活得多,並且還允許您添加最合適的toString
表示形式。
因此,假設lib.getSortedBooks()
返回一組Book
而不是Map.Entry
,則可以簡單地執行以下操作:
String output = lib.getSortedBooks().stream()
.map(Book::toString)
.collect(Collectors.joining(", "));
System.out
打印方法在內部使用toString()
,因此,當您調用toString()
您會得到與在輸出中看到的相同的東西。 然后,用箭頭替換等號。
System.out.printf(iterator.next().toString().replace("=", " -> ") + " ");
一種更優雅的方法(實際上是正確的方法,因為Map.Entry
對toString()
格式沒有任何保證):
Map.Entry<K, V> entry = iterator.next();
System.out.printf(entry.getKey() + " -> " + entry.getValue() + " ");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.