【问题标题】:Java map of map (nested map) sorting地图(嵌套地图)排序的Java地图
【发布时间】:2020-04-22 03:40:55
【问题描述】:

我有一个嵌套地图

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

另外,我有深度地图

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

我从 txt 文件中读取行并放入嵌套地图中,如下所示

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());
}

txt 文件的内容如

John AA 80
Adam BB 60
Natalie BB 65

name是map的key,grade是嵌套map的key,score是嵌套map的value。 那么,如何按分数降序对它们进行排序?

【问题讨论】:

  • 到目前为止你有什么尝试?
  • 我建议熟悉 Streams
  • 我尝试了 Collection.sort 和 compareTo 但我无法为嵌套地图配置它们。
  • 不相关:阅读 java 命名约定...使用 deepMap 并避免使用 "_" 。或者甚至更好:使用一个可以告诉读者在该地图中找到什么的名称。它是一个映射的事实可以在 IDE 中很容易地计算出来。那么,为什么不将其称为 namesById 或其他名称(告诉读者键是什么,值是什么)。

标签: java sorting hashmap linkedhashmap nested-map


【解决方案1】:

map 应该包含不同的deep_map 实例,否则map 的每个键都将具有相同的 Map 对象,并且您会覆盖值。

所以你只需要 field:

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

阅读可以如下。我没有使用所有功能,因为这需要很多解释。

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());
}

但是让数据按分数降序排列:

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());
}

还有更多功能使用:

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());
}

【讨论】:

  • 据我了解,分数是您代码中 sortedMap 的关键。但它应该是 deepMap 的值。我应该稍后更换它们吗?
  • 另一个问题是当有另一行等级和名称相同时,程序会覆盖它们,因为它们在 deepMap 中作为 key 一起保存。
  • 所以一个新的问题是读取 A B 10 和 A B 20 想存储最高的可能。也许您要存储的内容和要输出的内容有所不同。你甚至可能会想到class Student { String name; String course; List&lt;Integer&gt; scores; }
  • 实际上,问题是 A B 10 和 C D 10 的情况,因为分数存储为键。先生,您能告诉我您的电子邮件地址吗?
  • 我通常会这样做,但问题并没有那么有趣,从下周一开始我就开始工作了。尝试用笔和纸从逻辑上“解决”你的问题;然后你可以在一段时间后解决所有问题。并进行调试。祝你好运
【解决方案2】:

地图是按键排序的,所以我认为最好的方法是创建一个新的地图,它使用分数作为键,名称列表作为值。

但我不明白你的结构。

【讨论】:

  • 问题是地图的关键。我可以轻松地对nested_map 进行排序我的意思是我只能对一维哈希图进行排序。但我不能保留嵌套地图的键。当我使用可比较的类时,它会抛出错误,因为映射的值是 LinkedHashMap。够清楚吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多