【问题标题】:member of a collection?收藏的成员?
【发布时间】:2011-07-08 07:08:17
【问题描述】:

我有两个班级,Foo 和 Bar。每个 Foo 都有一个名称和一堆项目。 Bar 包含一堆 Foo,每个都有一个唯一的名称。

Bar 有一个方法 AddEntry,它接受一个 fooName 和一个项目 (1) 如果具有 fooName 的 foo 已经在 Bar 中,则将另一个项目添加到 Foo 或 (2) 如果具有 fooName 的 foo 不在 Bar 中, 创建一个具有该名称的 Foo 并将该项目添加到新的 Foo 中。

这是我如何实施的大纲。有没有更好的办法?我只是在学习Java,但这似乎很笨拙

class Foo { // a name and some items
    String fooName;
    List<Object> items = new ArrayList<Object>;
    Foo(name) {...} // create a named Foo
    AddtoFoo(item) {...} // add an item to this Foo
}

class Bar { // a bunch of foo's
    List<Foo> fooList = new Arraylist<Foo>;

    void AddEntry(String fooName, Object item) {
        boolean member = false;
        for(Foo foo : fooList){
            if{foo.name == fooName) {
                member = true;
                foo.AddtoFoo(item); // adds an item to this foo
                break;
             }
        }
        if(member == false) {
            Foo foo = new Foo(fooName); // creates a named foo
            foo.AddtoFoo(item);  // adds the item
            fooList.add(foo);  // maintain our list of foo's
        }

    }
}

【问题讨论】:

  • 你应该使用foo.name.equals(fooName)比较String的相等性
  • 你的例子是完整的,还是仅仅是一个表示?如果它完成了,您可以使用 Map> 来存储所有内容,然后使用 map 上的 contains 方法添加项目。
  • 这是一个表示,但关键是Bar包含一个Foos列表,每个Foos都有一个名称和一个项目列表。

标签: java collections


【解决方案1】:

我会使用 Map&lt;String, Foo&gt; 将 foo 名称映射到 foo 对象。

Map<String, Foo> fooMap = new HashMap<String, Foo>();

这样你就可以了

Foo foo = fooMap.get(fooName);
if( foo == null)
{
  foo = new Foo(fooName);
  fooMap.put(fooName, foo);
}
foo.AddtoFoo(item); 

【讨论】:

    【解决方案2】:

    在 bar 类中,您应该使用 HashMap 而不是 ArrayList,其中 FooName 作为键,Foo 作为对。由于 HashMap 有 o(1) 的搜索时间,您正在使用 arraylist 中的 for 循环迭代。

    【讨论】:

    • 试图不放弃代码 sn-p 认为@foosion 正在学习 :)
    【解决方案3】:

    如果 foo 的名称只是用于查找,那么 Map&lt;String,List&lt;Foo&gt;&gt;(并删除 Foo.name)可能会让您免于编写那么多代码。

    【讨论】:

      【解决方案4】:

      您可能想改用Map,您可以通过键查找对象。

      Map<String,Foo> fooMap = new HashMap<String,Foo>();
      foo.put("name_of_foo",new Foo());
      

      那么您的addEntry 可能如下所示:

      void addEntry(String fooName, Object item){
          Foo foo = fooMap.get(fooName);
          if(foo == null){
             foo = new Foo();
             fooMap.put(fooName,foo);
          }
          foo.addToFoo(item);
      }
      

      另外,您应该使用 foo.name.equals(fooName) 比较 String 的相等性

      【讨论】:

        【解决方案5】:

        您可以尝试在 Bar 中使用 HashMap,而不是使用 List。使用 fooName 作为唯一键。这样,在 Bar 中,您可以更快地检查 Foo 的实例在您当前的 bar 中是否已经知道(只是类似于此的内容):

        Map<String, Foo> fooMap = new HashMap<String, Foo>();
        
        ... 
        Foo foo = fooMap.get(fooName);
        if(foo == null)
        {
           fooMap.add(fooName, new Foo(fooName));
        }
        

        【讨论】:

          【解决方案6】:

          除非 foo 必须保持相同的顺序,否则您可以将 foo 列表替换为 Map&lt;String, Foo&gt;。搜索现有的 foo 将变成 O(1) 操作,而不是 O(n) 操作。

          即使 foo 必须保持有序,您也可以使用 LinkedHashMap。

          【讨论】:

            【解决方案7】:

            这是正确的,但如果您正在寻找正确的 foo 对象,而不是使用 List,请使用 Map,例如 HashMap。将fooName 用作键,将Foo 对象用作值。使用get(fooName)获取您正在查看的对象,如果返回null,则不存在,然后使用put()添加新的Foo

            【讨论】:

              【解决方案8】:

              最好的方法和更易于维护的方法是使用 hashCode 并使用 contains。

              公共 int hashCode() { 返回 fooName.hashCode(); }

              这必须比 for: 循环快。虽然它不会为您提供 O(1) 复杂度,但它保证(理论上)固定检索 ~ O(1)

              get() 方法也在 hashMap 上做同样的事情。它使用 hashCode 从 Map 中检索对象。

              【讨论】:

                猜你喜欢
                • 2012-04-27
                • 1970-01-01
                • 2010-09-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-10-10
                • 1970-01-01
                • 2020-08-16
                相关资源
                最近更新 更多