Reputation: 13
package A;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
class MapManager {
static Map<String, Double> readData(String str){
Map<String, Double> map = new TreeMap<String, Double>();
try {
BufferedReader br = new BufferedReader(new FileReader(str));
while(true) {
String line = br.readLine();
if(line == null) break;
String []sr = line.split(" ");
double num = Double.parseDouble(sr[1]);
map.put(sr[0], num);
}
br.close();
}catch(IOException e) {
e.printStackTrace();
}
return map;
}
}
public class A {
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);
}
}
output on screen is :
... But I want to make :
...
My professor said "You have to override toString in Class Map" but Map is interface then how can override tostring in Map..? And I can't modify public class A. If there are some idea that can make result that I want, please let me know:))
Upvotes: 1
Views: 964
Reputation: 44368
Other answers here omit the implementation of the overriden toString
method. Here they are:
// Java 8 way
@Override
public String toString() {
return entrySet().stream()
.map(e -> e.getKey() + " " + e.getValue())
.collect(Collectors.joining());
}
// general way (preferable for this use case IMHO)
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
forEach((key, value) -> sb.append(key).append(" ").append(value));
return sb.toString();
}
Now, the only thing you need to decide whether you want to have a reusable class with such overriden toString
method or just for one time use.
Class way
public class PrintableTreeMap<K, V> extends TreeMap<K, V> {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
forEach((key, value) -> sb.append(key).append(" ").append(value));
return sb.toString();
}
}
Map<String, Double> map = new PrintableTreeMap<>();
One time use way
Map<String, Double> map = new TreeMap<>() {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
forEach((key, value) -> sb.append(key).append(" ").append(value));
return sb.toString();
}
};
Upvotes: 0
Reputation: 1053
This is the easiest way:
TreeMap<String, Double> map = new TreeMap<String, Double>(){
@Override
public String toString() {
return "override here";
}
};
Upvotes: 2
Reputation: 4582
Map is reference, while in your case Object is TreeMap
. So you would need to override toString()
in TreeMap<K, V>
class. And use CustomTreeMap
rather than TreeMap
compared to current code. As below :
public class CustomTreeMap<K, V> extends TreeMap<K, V> {
private static final long serialVersionUID = 1L;
public String toString() {
// Your implementation goes here
}
}
From the AbstractMap
class, the default toString()
implementation is below. You can manipulate this code to get desired output.
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(' ');
}
}
Here in your case you can also make some use of Java 8, rather than the Iterator directly.
Upvotes: 1