首页 > 解决方案 > 如何覆盖 System.out.println(map)

问题描述

我想覆盖 System.out.println(map) 不打印 

{A=1, B=2, C=3,...}

但 

 A 1
 B 2
 C 3
 ...

就像我在 MapManager 类的 readData 函数中所做的一样。

我从 AbstractMap<K,V> 的定义代码中找到了一些可能是解决方案的提示,它由 TreeMap<K,V> 扩展并实现 Map<K,V> 在 AbstractMap<K, V>, toString() 的实现如下:

 public String toString() {
        Iterator<Entry<K,V>> i = entrySet().iterator();
        if (! i.hasNext())
         return "{}";
        StringBuilder sb = new StringBuilder();
        sb.append('{'); 
        for (;;) {
            Entry<K,V> e = i.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key); 
            sb.append('=');
            sb.append(value == this ? "(this Map)" : value);
            if (! i.hasNext()) return sb.append('}').toString();
            sb.append(',').append(' ');
             }
        }

如果我要修改此代码以使其执行我打算执行的操作,它将是这样的:

public String toString() {
    Iterator<Entry<K,V>> i = entrySet().iterator();
    if (! i.hasNext())return "{}";
    StringBuilder sb = new StringBuilder(); 
    sb.append('{');
    for (;;) {
        Entry<K,V> e = i.next();
        K key = e.getKey();
        V value = e.getValue();sb.append(key   == this ? "(this Map)" : key);
        sb.append(' ');  //whitespace instead of ‘=’
        sb.append(value == this ? "(this Map)" : value);
        if (! i.hasNext())return sb.toString();// make sb into String without appending anything.
        sb.append('\n'); //append newline instead of ‘,’ and ‘ ’
    }
}

但是 添加到这一点,我想按值的升序和键的字母顺序打印地图的条目,所以我想要 println 做的是以下说明会做的事情:

set = box.entrySet();
list = new ArrayList<>(set);
Collections.sort(list, new ValueComparator<Map.Entry<String, Double>>());
    
Iterator<Map.Entry<String, Double>> it = list.iterator();
while(it.hasNext()) {
    Map.Entry<String, Double> entry = it.next();
    double value = entry.getValue().doubleValue();
    System.out.println(entry.getKey() + " " + value);
}

我怎么能在我的代码中做覆盖来实现这一点? 一个重要的限制 是我不能修改 public class Problem{ } 中的代码。

下面是我写的整个代码:

import java.util.*;
import java.util.Map.Entry;
import java.io.*;

class MapManager{
    private static BufferedReader br;
    private static Set<Map.Entry<String, Double>> set;
    private static List<Map.Entry<String, Double>> list;

    static class ValueComparator<T> implements Comparator<T>{
        public int compare(Object o1, Object o2) {
            if(o1 instanceof Map.Entry && o2 instanceof Map.Entry) {
                Map.Entry<String, Double> e1 = (Map.Entry<String, Double>) o1;
                Map.Entry<String, Double> e2 = (Map.Entry<String, Double>) o2;
                double v1 = e1.getValue().doubleValue();
                double v2 = e2.getValue().doubleValue();
                return (int)(v1 - v2);
            }
            return -1;
        }
    }

    public static TreeMap<String, Double> readData(String fn){
        TreeMap<String, Double> box = new TreeMap<>();
        int data = 0, i = 0, j = 0, digits = 0, points = 0;
        String buffer = " ";
        String name = " ";
        String price = " ";

    (omitted)

        set = box.entrySet();
        list = new ArrayList<>(set);
        Collections.sort(list, new ValueComparator<Map.Entry<String, Double>>());
    
        Iterator<Map.Entry<String, Double>> it = list.iterator();
        while(it.hasNext()) {
            Map.Entry<String, Double> entry = it.next();
            double value = entry.getValue().doubleValue();
            System.out.println(entry.getKey() + " " + value);
        }

        return box;
    }
}
public class Problem {
    public static void main(String[] args) {
        Map<String, Double> map = MapManager.readData("input.txt");
        if(map == null) {
            System.out.println("Input file not found.");
            return;
        }
        System.out.println(map);
    }
}

标签: javaoverriding

解决方案


只需使用覆盖的toString方法创建您的地图。您可以将其分配给接口类型或TreeMap类型。

Map<String,Double> map = new TreeMap<>() {
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (Entry<?,?> e : this.entrySet()) {
            sb.append(String.format("%s %s%n", e.getKey(), e.getValue()));
        }
        return sb.toString();
    }
};
    
    
map.put("A",1.0);
map.put("B",2.0);
map.put("C",3.0);
    
System.out.println(map);

印刷

A 1.0
B 2.0
C 3.0

另一个建议。如果您必须编写自己的比较器,请不要这样做。

 return (int)(v1 - v2);

这是不好的形式。花点时间返回 -1、1 或 0。您可以使用三元运算符 ( ?:) 轻松完成。

 return v1 > v2 ? 1 : v1 < v2 ? -1 : 0;

但更好的是使用Map.Entry类提供的比较器。

Comparator<Entry<String,Double>> valueComparator = Entry.comparingByValue();
Collections.sort(List, valueComparator);
        


推荐阅读