1

I have a nested map as

Map<String, HashMap<String, Integer>> map = new TreeMap<String, HashMap<String, Integer>>();

Also, I have deep map as

HashMap<String, Integer> deep_map = new HashMap<String, Integer>();

I read lines from txt file and put in to nested map as below

try {
    FileInputStream fstream = new FileInputStream("file.txt");
    DataInputStream in = new DataInputStream(fstream);
    BufferedReader br = new BufferedReader(new InputStreamReader(in));
    String strLine;
    while ((strLine = br.readLine()) != null)  {
        String[] tokens = strLine.split(" ");
        deep_map.put(tokens[1], Integer.parseInt(tokens[2]));
        map.put(tokens[0], deep_map);
    }
    in.close();
} catch (Exception e) {
    System.err.println("Error: " + e.getMessage());
}

Content of txt file like

John AA 80
Adam BB 60
Natalie BB 65

Name is the key of map, grade is the key of nested map and score is the value of nested map. Thus, how can I sort them descending order of score?

6
  • 1
    What have you tried so far? Commented Jan 3, 2020 at 15:19
  • I suggest to get familiar with Streams Commented Jan 3, 2020 at 15:26
  • Possible duplicate of stackoverflow.com/questions/109383/… Commented Jan 3, 2020 at 15:28
  • I tried Collection.sort and compareTo but I can't configure them for nested map. Commented Jan 3, 2020 at 15:31
  • Unrelated: read about java naming conventions ... use deepMap and avoid the "_" . Or even better: use a name that tells the reader what to find in that map. The fact that it is a map can be easily figured within an IDE. So, why not call it namesById or something (that tells the reader what the keys are, and the values). Commented Jan 3, 2020 at 15:43

2 Answers 2

1

The map should contain different deep_map instances, as otherwise every key of map would have the same Map object, and you have overwritten values.

So you only need as field:

SortedMap<String, Map<String, Integer>> map = new TreeMap<>();

The reading can go as below. I do not use all features, as that would need much explanation.

Path path = Paths.get("file.txt");
try (Stream<String> lines = Files.lines(path, Charset.defaultCharset()) {
    lines.map(line -> line.split(" "))
            .filter(tokens -> tokens.length == 3)
            .forEach(tokens -> {
                Map<String, Integer> deepMap = map.get(tokens[0]);
                if (deepMap == null) {
                    deepMap = new HashMap<String, Integer>();
                    map.put(tokens[0], deepMap);
                }
                deepMap.put(tokens[1], Integer.parseInt(tokens[2]));
            });
} catch (IOException e) {
    System.err.println("Error: " + e.getMessage());
}

HOWEVER to have data ordered with descending score:

SortedMap<Integer, Map<String, String>> scoreToCourseToName =
    new TreeMap<>(Comparator.reversed());
Path path = Paths.get("file.txt");
try (Stream<String> lines = Files.lines(path, Charset.defaultCharset()) {
    lines.map(line -> line.split(" "))
            .filter(tokens -> tokens.length == 3)
            .forEach(tokens -> {
                Integer score = Integer.valueOf(tokens[2]);
                Map<String, String> deepMap = scoreToCourseToName.get(score);
                if (deepMap == null) {
                    deepMap = new TreeMap<String, Integer>();
                    scoreToCourseToName.put(score, deepMap);
                }
                deepMap.put(tokens[1], Integer.parseInt(tokens[0]));
            });
} catch (IOException e) {
    System.err.println("Error: " + e.getMessage());
}

And with more feature using:

SortedMap<Integer, Map<String, String>> scoreToCourseToName =
    new TreeMap<>(Comparator.reversed());
Path path = Paths.get("file.txt");
try (Stream<String> lines = Files.lines(path, Charset.defaultCharset()) {
    lines.map(line -> line.split(" "))
            .filter(tokens -> tokens.length == 3)
            .forEach(tokens -> {
                Integer score = Integer.valueOf(tokens[2]);
                Map<String, String> deepMap =
                    scoreToCourseToName.computeIfAbsent(score, sc -> new TreeMap<>());
                deepMap.put(tokens[1], Integer.parseInt(tokens[0]));
            });
} catch (IOException e) {
    System.err.println("Error: " + e.getMessage());
}
Sign up to request clarification or add additional context in comments.

5 Comments

As ı understood, score is key of sortedMap in your code. But it should be value of deepMap. Just should I replace them later ?
Another problem is when there are another row that grade and name are same, program overwrite them, because they keep as key in deepMap together.
So one new problem is reading A B 10 and A B 20 one wants to store the highest probably. Maybe there is a difference what you want to store and what you want to output. You might even think of a class Student { String name; String course; List<Integer> scores; }.
Actually, Problem is A B 10 and C D 10 case because score store as key. Can you share your e-mail address with me sir ?
I would do that normally, but the problem is not that much interesting and as of next Monday I am deep into work. Try to "solve" your problem logically with pen and paper; then you can solve every problem after a while. And do debugging. Good luck
0

Maps are sorted by the key so I think the best way is to create a new Map which uses score as key and a List of names as value.

But I don't understand your structure.

1 Comment

Problem is key of map. I can sort easily nested_map I mean I can sort only 1d hashmap. But I can't keep key of nested map. When I use comparable class, it throws error because value of map is LinkedHashMap. Is it clear enough ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.