簡體   English   中英

自定義TreeSet打印Map.Entry值的方式

[英]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.EntrytoString()格式沒有任何保證):

Map.Entry<K, V> entry = iterator.next();
System.out.printf(entry.getKey() + " -> " + entry.getValue() + " ");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM