gpt4 book ai didi

java - HashMap 的多映射更好的数据结构

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:49:42 24 4
gpt4 key购买 nike

事实证明,我选择的数据结构设计执行起来非常笨拙,因此与其征求您的专家意见如何执行它,我希望您能为我正在尝试的内容建议一个更自然的数据结构做,如下。我正在读取数据行。每列都是一个变量(Animal、Color、Crop,... - 共有 45 个)。每行数据都有该列变量的值 - 您事先不知道这些值或行数。

Animal  Color   Crop    ...
-------------------------------------
cat red oat
cat blue hay
dog blue oat
bat blue corn
cat red corn
dog gray corn
... ... ...

当我读完后,它应该捕获每个变量、该变量所取的每个值以及该变量取该值的次数,如下所示:

Animal [cat, 3][dog,2][bat, 1]...
Color [blue, 3][red,2][gray,1]...
Crop [corn,3][oat, 2][hay,1]...
...

我尝试了几种方法,我得到的最接近的方法是使用 GUAVA multi map of hash maps,如下所示:

Map<String, Integer> eqCnts = new HashMap<String, Integer>();
Multimap<String, Map> ed3Dcnt = HashMultimap.create();
for (int i = 0; i + 1 < header.length; i++) {
System.out.format("Got a variable of %s\n", tmpStrKey = header[i]);
ed3Dcnt.put(tmpStrKey, new HashMap<String, Integer>());
}

看起来我已经完全创建了我想要的东西,但是使用起来非常笨拙和乏味,而且它的行为方式很神秘(一方面,即使“ed3Dcnt.put()”插入了一个HashMap,相应的“.get()”不返回一个HashMap,而是一个Collection,这会产生一系列新的问题。)请注意,我想根据值从高到低对结果进行排序,但我认为我可以轻松做到这一点。

那么,如果您愿意,请就更好的数据结构设计选择提出建议?如果没有明显更好的设计选择,我如何使用 .get() 返回的 Collection,而我只需要放入该插槽的单个 HashMap?

非常感谢 - Ed

最佳答案

您可以通过替换 Map<String, Integer> 来消除一些奇怪的地方通过 Multiset .

A multiset (or a bag)是一个允许重复元素的集合 - 并对它们进行计数。你又扔了一个苹果、一个梨和一个苹果。它记得它有两个苹果和一个梨。基本上,这就是您在 Map<String, Integer> 下的想象你刚刚用过的。

Multiset<String> eqCounts = HashMultiset.create();

the corresponding ".get()" does not return a HashMap, but rather a Collection

这是因为您使用了通用的“Multimap”界面。文档说:

You rarely use the Multimap interface directly, however; more often you'll use ListMultimapor SetMultimap, which map keys to a List or a Set respectively.


因此,坚持您的原始设计:

  • 每一列都是一个 Multiset<String>它将存储和计算您的值。
  • 你会得到一个 Map<String, Multiset<String>> (键是标题,值是列)您将像这样放置列:

    Map<String, Multiset<String>> columns = Maps.newHashMap();
    for (int i = 0; i < headers.length; i++) {
    System.out.format("Got a variable of %s\n", headers[i]);
    columns.put(headers[i], HashMultiset.<String>create());
    }

读取一行并将值放在它们所属的位置:

String[] values = line.split(" ");
for (int i = 0; i < headers.length; i++) {
columns.get(headers[i]).add(values[i]);
}

综上所述,您可以看到外部 HashMap有点多余,整个事情仍然可以改进(尽管我认为它已经足够好了)。要进一步改进它,您可以尝试以下方法:

  1. 使用 Multiset 的数组而不是 HashMap .毕竟,您事先知道列数。
  2. 如果您对创建通用数组感到不自在,请使用 List.
  3. 可能是最好的:创建一个类 Column像这样:

    private static class Column {
    private final String header;
    private final Multiset<String> values;

    private Column(String header) {
    this.header = header;
    this.values = HashMultiset.create();
    }
    }

    而不是使用 String[]标题和 Map<String, Multiset<String>>对于它们的值,请使用 Column[] .您可以创建此数组来代替创建 headers数组。

关于java - HashMap 的多映射更好的数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17131554/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com