java - 如何覆盖 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);
}
}
解决方案
只需使用覆盖的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);
推荐阅读
- python - 如何锁定一些行以在 Django 中插入?
- reactjs - 而不是从数组中删除项目,它被设置为未定义
- mysql - PHPMYADMIN | 我们如何在两个不同的 MySQL 数据库中同步两个表(在同一台服务器内)?
- vue.js - 路由器推送后 Nuxt 正在重新加载页面
- css - Bootstrap Dropdown 出现在其他元素的后面
- reactjs - 是什么导致错误:此代码中的重新渲染过多?
- sql - 执行以下 Oracle 查询时出错
- amazon-web-services - 将 docker Image 推送到 AWS ECR 时出现标记问题
- reactjs - 单击表单按钮时,Ant Design 表单元素未提交
- c++ - 在 C++ 中传递给 MPI 的结构