Reputation: 33
I am trying to sort a nested HashMap,
HashMap<Integer, HashMap<Integer, String>> myMap = new HashMap<>()
, by a specific value in the inner HashMap.
The program reads a delimited file that contains the following values:
000001014|A||Harvey|T|Dent|05/27/1991|0902|000001014|05/27/1991|01/01/3000| 000001388|A||Tony|K|Stark|09/19/1992|0054|000001388|09/19/1992|01/01/3000| 000001395|A||Steve|C|Rogers|10/26/1992|7402|000001395|10/26/1992|01/01/3000| 000001396|A||Peter|P|Parker|11/02/1992|1002|000001396|11/02/1992|01/01/3000| 000011148|I||Drax|T|Destroyer|02/17/1992|7005|000011148|02/17/1992|01/01/3000| 000011141|A||Rocket|M|Raccoon|02/10/1992|7170|000011141|02/10/1992|01/01/3000|000001404|A||Natasha||Romanoff|12/28/1992|7240|00001404|12/28/1992|01/01/3000| 000001442|A||Bruce|T|Banner|10/06/1993|7012|000001442|10/06/1993|01/01/3000| 000001450|A||Scott|L|Lang|11/29/1993|0002|000001450|11/29/1993|01/01/3000| 000001486|A||Thor|J|Odinson|07/04/1994|0002|000001486|07/04/1994|01/01/3000|
I chose a Nested HashMap so that each line in the file has its own key and then each element in each line has a key. For example myMap.get(0).get(7) returns 0902, myMap.get(1).get(7) returns 0054, myMap.get(2).get(7) returns 7402. But the problem is that sorting the HashMap by the nested HashMap value has been a real humdinger. So, what I am trying to accomplish is to sort the whole HashMap by the 7th element in the inner map.
Should I sort myMap the old fashion way using a nested loops and binary sort or insertion sort? How do I tackle this problem?
private static Path directory() {
File home = FileSystemView.getFileSystemView().getHomeDirectory();
String path = home.getAbsolutePath();
Path dir;
//For reference Directory
C:\Users\PC_USER_NAME\Desktop\Work\Person\Employees.txt
if(getProperty("os.name").startsWith("Windows")) {//specify your
directory Windows
dir = Paths.get(path + File.separator + "Work" + File.separator + "Person");
} else {//Specify your directory Mac
dir = Paths.get(File.separator + "Users" + File.separator +
getProperty("user.name") + File.separator + "Desktop" + File.separator + "Work" + File.separator + "Person");
}
return dir;
}
private static void readFile() {
HashMap<Integer, HashMap<Integer, String>> myMap = new HashMap<>();
HashMap<Integer, String> inner = new HashMap<>();
BufferedReader reader;
String line;
int count = 0;
try {
File dir = new File(directory().toString());
File[] files = dir.listFiles((File pathname) ->
pathname.getName().startsWith("Employees"));
File lastModifiedFile = files[0];
for (File file : files) {
if (lastModifiedFile.lastModified() < file.lastModified()) {
lastModifiedFile = file;
}
}
reader = new BufferedReader(new FileReader(lastModifiedFile));
//Skips the header.
reader.readLine();
while((line = reader.readLine()) != null) {
String[] keyValue = line.split("\\|");
for (int i = 0; i < keyValue.length; i++) {
inner.put(i, keyValue[i]);
}
myMap.put(count, inner);
count++;
inner = new HashMap<>();
}
reader.close();
} catch (IOException e) { e.printStackTrace(); }
sort(myMap);
}
private static void sort(HashMap<Integer, HashMap<Integer, String>> myMap) {
Set<Entry<Integer, HashMap<Integer, String>>> sorted =
myMap.entrySet();
for(Entry<Integer, HashMap<Integer, String>> entry : sorted) {
System.out.println(entry.getKey() + " ==> " + entry.getValue().get(7));
}
//Won't add this method code for brevity sake
writeFile();
}
Upvotes: 0
Views: 44
Reputation: 13581
First of all - what does it mean to sort a HashMap? To print sorted values as I guess what does mean you won't be sorting Map
itself, but some kind of collection of it's values
Second thing - why do you want to keep such data in a Map
? It sounds like really bad idea, and you just spotted the first argument why
For me you should create some kind of Row
class like
public class Row {
private List<String> items; // for '|' splitted values in a row, maybe it should be even String[]?
...
}
and keep your whole file as a List<Row>
. Then you can create your own Comparator or even make Row
implements Comparable
public class Row implements Comparable<Row>{
private List<String> items = new ArrayList<>();
...
@Override
public int compareTo(Row that) {
return this.items.get(8).compareTo(that.items.get(7));
}
}
Now you can easily sort the file using Collections.sort()
util
Please notice that implementing Comparator
allow you to create many versions of them (like SortBy6thComparator
, SortBy7thComparator
, SortBy8thComparator
...). You just need to use then another version of sort
method:
public static <T> void sort(List<T> list, Comparator<? super T> c)
Upvotes: 1