【问题标题】:which datastructure should i use based on my needs?根据我的需要,我应该使用哪种数据结构?
【发布时间】:2012-10-12 19:42:47
【问题描述】:

需求:

  • 存储覆盖等于和哈希码的类的对象
  • 将循环并将对象推入数据结构中
  • 需要能够调用contains来检查结构中是否存储了某个对象
  • 如果contains 返回true,则从结构中获取该特定对象并在该对象上调用某个getter

我考虑过的选项:

  • Map - 这适用于所有需求,但我并没有真正的地图(键和值)。我所拥有的只是一堆物体。通过将对象存储为键和整数或值中的其他内容来强制使用映射是否是一种好习惯?

  • Set 可以,但是它没有 get 之类的 fetch 方法。

  • List 也可以,但它没有非基于索引的获取方法。意思是,一旦contains 返回true,我将不得不遍历列表以找到我的特定对象的索引,然后获取它。

我愿意使用不同的库,例如 apache commons 或 guava。

【问题讨论】:

  • 有趣的是,你不需要地图,但你需要一个获取方法:-) 你想获取什么?我想的对象。并基于什么标准?不,将对象存储为键(集合?)并将整数存储为值并不是一个好主意。这会浪费内存并引入另一个调试向量。

标签: java data-structures architecture


【解决方案1】:

List 也可以,但它没有非基于索引的获取方法。

List 有一个 indexOf(Object) 方法,它可以完全按照您的意愿进行操作。

【讨论】:

  • 他不需要indexOf 方法,因为他的对象不是通过索引检索的,索引是键的特化。 OPs question的最后一段也提到了这一点。
  • 你读过OP的最后一点吗?他说List 不合适,因为他无法获得用于contains() 的对象的索引。这就是indexOf() 提供帮助的地方。
  • 不,他说的是“列表也可以工作,但它没有非基于索引的获取方法”。他想要一种基于索引的方法。那是因为他不知道索引。他要做的是创建一个对象,由于该类实现了equals,他将简单地调用contains。当然,这一切都取决于equals 的实现。
  • @amn.. 他不知道他有一个名为 :- indexOf 的方法可以为他获取index。他不想Loop,如果你建议的是Set,他将不得不这样做。
  • @amn。普通人。你不能重新阅读OP而不是争论吗?为什么你认为他不需要迭代?如何在不循环的情况下从Set 获取数据??
【解决方案2】:

虽然在这个scenario 中使用的best thing 将是一个Map,因为它提供了基于Key-Value 对的快速检索。

List 也允许基于索引获取数据。

因此,您可以使用ListMap。但为了让您的任务更轻松,我更喜欢Map。因为我是Map,所以您不必搜索对象的index,然后在该索引处获取Object。获取只是一个one-line 操作。

// When using a List.
List<String> myList = new ArrayList<String>();
if (myList.contains("rohit")) {
    myList.get(myList.indexOf("rohit"));
}

// When using Map.
Map<String, String> myMap = new HashMap<String, String>();
// You can directly fetch your object, based on some Key if you have one..
myMap.get("key"); 

【讨论】:

  • 为什么要投反对票?在您投反对票后发表评论会更有成效。这样帖子就可以即兴发挥了。
  • 当然是@Rohit。根据 OPs 标准,您的答案根本不是一个好的答案。我很抱歉遇到这样的事情。请检查他的明确要求——他需要的是一套。你只是用你的列表来模拟一个集合,为什么?一组用于提供contains 方法,利用equalshashCode,将对象“循环并推入”其中,如果您想检查它是否包含对象,那么您(再次)拨打contains(object)
  • @amn.. 你还必须注意到他不想迭代来获取数据。 Set 没有获取索引的方法。因此,即使他知道 Set 包含该对象,他也必须进行迭代。这就是我发布两个选项的原因。
  • 真的吗?他如何知道要从您的列表中获取什么对象?
  • @amn.. 你没看到我的例子??使用indexOf() 方法。我已经发布了代码
【解决方案3】:

你需要一套。您不需要 fetch 方法(您认为您需要),因为就像您说的那样,您只有一堆对象。而且由于这些使用equalshashCode,因此您需要的正是一套。

当然 map 也可以,因为它的键也是一个集合,但最后你需要更好地指定你的要求,因为看起来你对数据结构的目的有点困惑。据我了解,您确实不需要地图。

哈希集实现就可以了。以下是您可以使用的全部内容:

class Foo
{
    final String name;

    Foo(String name)
    {
        this.name = name;
    }

    boolean equals(Object obj)
    {
        return (obj instanceof Foo) && ((Foo)obj).name.equals(name);
    }
}

Set<Foo> fooSet = new HashSet<Foo>();

fooSet.add(new Foo("someFoo"));

assert fooSet.contains(new Foo("someFoo"));

【讨论】:

  • @amn.. 好的,现在您知道您的 Set 包含您的对象.. 现在您将如何获取它?当然使用loop。那是OP不想要的。请重新阅读OP
  • 不,您不太了解equals 的作用——如果对象相等,则不需要“原始”对象。对象内的数据封装确保您可以使用您创建的与集合中的对象相等的任何新对象。 当然,除非*他**确实需要索引或键,这使我的回答无效。但这取决于他的对象的性质。我只是回应他的要求。
  • @amn contains() 只会告诉他它被包含了,但除了循环获取它别无他法。 list 也有 contains(),但另外还有 indexOf()。如果您争辩说他不必从Collection 取回对象,那么使用ListSet 没有任何区别。如果我建议List,就没有理由投反对票。
  • @amn.. 好的,我会在这里澄清一下。支持 OP 想要检查 List 是否包含Object。现在,您是对的,他可以使用contains 方法检查它并使用他正在比较的object。但是如果他想修改Set里面的Object呢?你如何处理这个案子?嗯?
  • @Baz,你不需要得到任何东西 - equals 意味着对象是平等的,任何一个都可以。如果两个字符串对象都将“apple”作为值,则认为它们相等,即使它们实际上是两个不同的对象,占据内存中的不同位置。您的列表和/或地图为他检索原始对象,这违背了equalshashCode 的观点。
猜你喜欢
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
相关资源
最近更新 更多