【问题标题】:Java - divide Hashtable into listsJava - 将 Hashtable 划分为列表
【发布时间】:2013-11-26 01:11:13
【问题描述】:

我有例如这些对:

key => name:

"name" => "myname1"
"height" => "myheight1"
"name" => "myname2"
"height" => "myheight2"

现在,如果我将所有这些都放入 Hashtable,那么第二个 nameheight 键将覆盖第一个键 nameheight 键名。我可以将它添加到两个不同的哈希表中,但在运行之前,我不知道这样的对会有多少,所以我不知道我需要多少个哈希表。那么如何将这些 paris 添加到列表中(在运行前不知道此类对的确切数量(例如,有时可能有三个名称键和两个高度键及其值等)。

所以当我添加所有这些值时,我需要在一个列表中显示如下:

list<list<Object>> = [[{name=myname1, height=myheight1}], [{name=myname2, height=myheight2}]]

例如,如果存在不同数量的此类对,例如两个名称和三个高度对:

list<list<Object>> = [[{name=myname1, height=myheight1}], [{name=myname2, height=myheight2}], [{height=myheight3}]]

注意:我从 xml 文件中获取这些对,因此它们在某种程度上是分组的,就像每次迭代我都会得到一组这样的对。例如

<main>
  <group>
    <name>myname1</name>
    <height>myheight1</height>
  </group>
  <group>
    <name>myname2</name>
    <height>myheight2</height>    
  </group>
</main>

那么我怎样才能正确地将这样的对添加到列表中,这样键就不会相互覆盖,以后我可以从列表中得到任何我想要的对?

【问题讨论】:

  • 考虑使用List&lt;Map&lt;String,String&gt;&gt;
  • 考虑使用List&lt;Group&gt;,其中 Group 是一个具有 name 属性和 height 属性的类。 Java 是一种面向对象的语言。定义和使用您自己的类。
  • Map&lt;String,List&lt;String&gt;&gt;
  • @McDowell 好的,我会在列表中使用 Map,那么我需要使用哪些键?就像现在我没有看到一样。或者你只是建议在迭代时生成键,比如第一次迭代键是一个,第二个是两个等等?
  • @Andrius 键将是元素的本地名称(名称、高度等)。每个地图代表一个组。有一个组列表。

标签: java xml list arraylist hashtable


【解决方案1】:

为什么不直接使用列表:

List<Group> groups = new ArrayList<Group>();

Group 定义为

public class Group {
    private final String name;
    private final int height;

    public Group(String name, int height) {
        this.name = name;
        this.height = height;
    }

    // getters are left as an exercise to the reader
}

(根据高度的表示,您可能需要使用除 int 以外的其他类型)。

编辑

另一种选择是使用诸如 Groovy 之类的动态语言,这会使此类任务变得更加容易(因为您不必跟踪 XML 文档结构)。这是一个例子:

http://groovyconsole.appspot.com/edit/1445001

【讨论】:

  • 如果以后我会得到 xml,那里会有第三对不同的对,比如weight =&gt; value?如果发生这种情况,我想每次都需要更新班级组?
  • 是的,就像您的程序的其余部分一样,为了使用这些新信息。但至少,一切都是类型安全的,并且被正确封装。
【解决方案2】:

一般情况下,您可以使用Map&lt;String,List&lt;String&gt;&gt;(如果您不关心顺序,则可以使用Set 作为第二个参数)。

更具体地说,如果您的数据是结构化的,那么您的代码和类也应该是结构化的。在这种情况下,请考虑创建一个 Group 类来保存您的(半)结构化数据:

public class Group {
    String name , height;
    // constructor, getters, setters
}

并将对象填充到List&lt;Group&gt;(或Set,如上所述)。要检索这些对,您只需遍历 List:

List<Group> groups = ....
for ( Group g : groups ) {
    System.out.println( "name=>" + g.getName() + ", height=>" + g.getHeight() );
}

干杯,

【讨论】:

  • 如果我把它塞进创建的类。我怎样才能轻松地从中获取 name=>value, height=>value 之类的对?因为我需要它们在其他地方使用。
  • 所有Group都将是你的配对。 nameheight 的 getter 将返回值。
【解决方案3】:

我宁愿去新班说

Class Entry
{
  String name;
  String height
}

现在添加条目到List&lt;Entry&gt;

【讨论】:

    【解决方案4】:

    正如其他一些答案所说,您可能需要将“值”类型设置为列表。

    class MyClass {
        ....    
        Map<String, List<String>> myMap = new HashMap<String, List<String>>();
        ....
        public void addPair(final String key, final String value) {
            if (myMap.containsKey(key)) {
                myMap.get(key).add(value);
            } else {
                final List<String> newList = new ArrayList<String>();
                newList.add(value);
                myMap.put(key, newList);
            }
        }
    

    }

    【讨论】:

    • 在这个解决方案中,您失去了姓名和身高之间的任何关系。这不太可能是发布者最终想要的,即使他没有表达过这个愿望。
    • 是的,当然我需要保持键和值之间的关系,然后是组或这些对之间的关​​系