【问题标题】:Java datastructure to map multiple keys to the same valueJava数据结构将多个键映射到相同的值
【发布时间】:2010-06-15 15:24:00
【问题描述】:

在 Java 中,我正在寻找一种将多个键映射到相同值的方法。假设我有数字 0-9 作为键,“x”、“y”和“z”作为值如下:

0->y
1->y
2->y
3->x
4->x
5->y
6->z
7->y
8->z
9->z

现在 x,y 和 z 是很长的字符串,而且我有数百万个键,所以我不能多次存储这些字符串。你会怎么做?

我的一个想法是创建两个数组:生成一个人工的第二个键,原始键映射到该键,另一个数组中的键是实际值的键。这样,值只存储一次,原始键仍然可以间接映射到值:

0->k1
1->k1
2->k1
3->k2
4->k2
5->k1
6->k3
7->k1
8->k3
9->k3

k1->y
k2->x
k3->z

问题:是否有更好的数据结构?

【问题讨论】:

    标签: java data-structures


    【解决方案1】:

    任何Map<Integer,String> 都可以——你只存储对字符串的引用,而不是它的副本,所以它有多长并不重要。

    如果您要多次构建相同的字符串值,请使用intern() 为该值每次获取相同的字符串对象。

    【讨论】:

    • 皮特,够公平的。我真的没有时间写一篇关于它的论文,所以我刚刚删除了评论。
    • 绝对是一个正确的答案,但不必map.put(k,v) 重复值不是很好吗?做类似map.put(k1, k2, ... , kn, v) 这样的事情会很好。
    【解决方案2】:

    我不太明白这个问题。如果您有一个字符串数组:String[] arr,那么只需为同一个对象设置不同的索引 - 也就是使引用相同。

    String[] map = new String[10];
    String x = "foo";
    String y = "bar";
    String z = "baz";
    map[0] = x;
    map[1] = y;
    map[2] = x;
    //...
    

    【讨论】:

      【解决方案3】:

      为什么不反转键/值对?使用 Set 或数组作为值:

      x->{3, 4}
      y->{0, 1, 2, 5, 7}
      z->{6, 8, 9}
      

      【讨论】:

        【解决方案4】:

        如果您不喜欢 Pete Kirkham 的建议(这将是最好的方法,IMO),您可以使用 Google Collections(呃...Guava 现在)MultiMap

        【讨论】:

        • 我也打算推荐 MultiMap,但他正在寻找映射到相同值而不是相反值的多个键。
        【解决方案5】:

        每个映射条目将使用数百位来表示理论上可以保留在 2 中的值。

        如果键比每几百个整数大约 1 的某个数字更密集,则根本不使用映射会更快更小,而是使用数组 - 类似于 Trove TByteArrayList - 其中字节值映射到您的字符串。如果您想获得 4 倍以上的密度,请将 4 个值打包到一个字节中。

        只有当你有大量数据时才需要考虑这个问题 - 但你说的是数百万个键,所以我认为它很合适。

        【讨论】:

          【解决方案6】:

          Java 会自动为您合并字符串引用,因此您无需手动执行以节省内存。您可以将键/值放在 HashMap 中。

          【讨论】:

          • 这不是真的。如果它是文字,编译器将实习字符串,以便相等的文字被相同的字符串对象替换,您可以手动调用intern(),但Java 永远不会在运行时隐式/自动执行任何此操作。一旦你有一个 String 的引用,Java 就不会将该引用更改为指向幕后的其他一些引用,并且你总是可以使用 new 关键字拥有相同字符串的唯一实例。因此,例如,从输入流或用户输入中读取的字符串都不会发生这种情况。
          猜你喜欢
          • 2020-12-14
          • 1970-01-01
          • 2020-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多