【问题标题】:Searchable list of objects in JavaJava中可搜索的对象列表
【发布时间】:2011-02-01 04:57:42
【问题描述】:

我想创建一个大型(约 300,000 个条目)Drug 类的自定义对象列表。 每个药物都有一个 ID,我希望能够通过该 ID 以对数时间搜索药物。 我必须使用什么样的列表? 如何声明它应该可以通过 ID 进行搜索?

【问题讨论】:

  • ID 的范围是多少?
  • 有没有机会将它们放入数据库中并让它在 SQL/JDBC 的帮助下完成工作?这无疑会更加快速和高效。
  • @BalusC 仅当数据变化不大时。如果他必须在短时间内更新所有内容并且不需要持久性,那么数据库将没有多大意义。但我的第一个想法也是指向数据库。

标签: java list search


【解决方案1】:

你不会使用 TreeMap 而不是 List 使用 ID 作为 Key 吗?

【讨论】:

  • 仅供参考,我建议 TreeMap 的原因是因为 TreeMap 保证运行包含、获取和放入 O(log n)
  • 如果您不需要订购钥匙,那么这是不必要的
  • 要求是对数搜索,所以我认为必须是。
  • TreeMap 的优点是可以按键顺序检索项目。原始问题中并未将其列为要求,尽管这当然不能证明这不是要求。但是 HashMap 满足了对数搜索的要求。如果这是唯一的问题,则不需要 TreeMap。
  • 由于用户最初建议使用列表,因此似乎需要顺序。但确实如此,没有明确说明。
【解决方案2】:

Map 接口的各种实现应该做你想做的事。

如果您打算使用 HashMap,请记住覆盖 Drug 类的 hashCode() 方法。

【讨论】:

  • 不是我不相信你,而是提醒我为什么 hashCode() 必须被覆盖?默认的不是很好吗?
  • 只有当你想使用你的类作为Map的key或者你想把它放进去时,你才需要实现hashCode和equals在Set。如果您只是想将它用作 Map 的值,那么您不需要实现它们。另外:如果你实现了equals(),那么你必须也实现hashCode()。
  • 对哈希码进行细粒度控制可以保证映射条目在存储桶之间均匀分布。最坏的情况是当所有条目都落在同一个桶中并且查找的复杂度变为 O(n)。
  • 默认实现只是将内存中的地址作为哈希码。如果您使用 Drug 对象作为键,则不能执行以下操作: myMap.put(new Drug("Whatever"), 23.42); myMap.get(new Drug("随便"));因为两个 Drug 实例都有不同的 hashCode 并且后者将返回 null。详情请见java.sun.com/javase/6/docs/api/java/lang/Object.html#hashCode()。
  • 假设ID的类型是String,并且这是关键,没有必要(也没有办法)覆盖equals(Object)和hashCode()方法。
【解决方案3】:

如果按键搜索对您很重要,那么您可能需要使用 Map 而不是 List。来自Java Collections Trail:

三个通用地图 实现是 HashMap、TreeMap 和 LinkedHashMap。如果你需要 SortedMap 操作或键排序 集合视图迭代,使用 树图;如果你想要最大速度和 不关心迭代顺序,使用 哈希映射;如果你想要近 HashMap 性能和插入顺序 迭代,使用 LinkedHashMap。

【讨论】:

    【解决方案4】:

    由于条目数量众多,您可能会考虑使用数据库而不是将所有内容都保存在内存中。

    如果你仍然想把它保存在内存中,你可以看看 b-trees。

    【讨论】:

      【解决方案5】:

      您可以使用任何列表,只要它已排序,您就可以使用binary search。 但我会使用在 O(1) 中搜索的 Map。

      【讨论】:

        【解决方案6】:
        public class Drug implements Comparable<Drug> {
        
            public int compareTo(Drug o) {
                 return this.id.compareTo(o.getId());
            }
        }
        

        然后在你的列表中你可以使用 binarySearch

            List<Drug> drugList; <--- List of all drugs
            Drug drugToSearchFor; <---- The drug that you want to search for, containing the id
            // Sort before search
            Collections.sort(drugList);
            int index = Collections.binarySearch(drugList, drugToSearchFor);
        
            if (index >= 0) {
                return true;
            } else {
                return false;
            }
        

        【讨论】:

          【解决方案7】:

          我知道我对这个声明很多余,但正如大家所说,这不正是 Map 的情况吗?

          【讨论】:

            猜你喜欢
            • 2011-07-08
            • 2012-10-19
            • 1970-01-01
            • 1970-01-01
            • 2012-06-20
            • 2016-08-10
            • 1970-01-01
            • 2017-03-17
            相关资源
            最近更新 更多