【问题标题】:Iterator seems to be losing data java迭代器似乎正在丢失数据 java
【发布时间】:2015-12-23 23:27:52
【问题描述】:

我有一个返回哈希图列表的方法(数据来自 ResultSet)。 在尝试使用迭代器循环数据并将其转换为字符串数组时,我发现代码不起作用 - 在循环时似乎丢失了一半的数组数据。

当交换它以使用 for 循环而不是迭代器时,数据不会丢失。我尝试同时使用 Iterator()ListIterator() 均无济于事

这是我的原始代码(不起作用):

public String[][] getLayoutEdges() throws SQLException {
    ArrayList<String[]> returnArray = new ArrayList<>();

    List<HashMap> layoutEdges = db.getLayoutEdgesFromDatabase();
    ListIterator<HashMap> edgesIterator = layoutEdges.listIterator();

    while(edgesIterator.hasNext()) {
        ArrayList<String> tmpList = new ArrayList<>();
        tmpList.add(edgesIterator.next().get("fromnode").toString());
        tmpList.add(edgesIterator.next().get("tonode").toString());
        tmpList.add(edgesIterator.next().get("distance").toString());

        String[] tmpStr = new String[tmpList.size()];
        returnArray.add(tmpList.toArray(tmpStr));

    } 

    String[][] rtn = new String[returnArray.size()][returnArray.size()];
    return returnArray.toArray(rtn);
}

下面是有效的代码:

public String[][] getLayoutEdges() throws SQLException {
    ArrayList<String[]> returnArray = new ArrayList<>();

    List<HashMap> layoutEdges = db.getLayoutEdgesFromDatabase();

    for(HashMap tmp : layoutEdges) {
        ArrayList<String> tmpList = new ArrayList<>();
        tmpList.add(tmp.get("fromnode").toString());
        tmpList.add(tmp.get("tonode").toString());
        tmpList.add(tmp.get("distance").toString());

        String[] tmpStr = new String[tmpList.size()];
        returnArray.add(tmpList.toArray(tmpStr));
    }

    String[][] rtn = new String[returnArray.size()][returnArray.size()];
    return returnArray.toArray(rtn);
}

谁能告诉我为什么迭代器不工作?我可以使用 for 循环,但我一生都无法弄清楚为什么我编写的原始迭代器代码没有保留我的所有数据。想知道我是否遗漏了一个步骤,或者我是否尝试使用错误的解决方案。

【问题讨论】:

    标签: java arraylist iterator hashmap


    【解决方案1】:

    因为这几行:

    tmpList.add(edgesIterator.next().get("fromnode").toString());
    tmpList.add(edgesIterator.next().get("tonode").toString());
    tmpList.add(edgesIterator.next().get("distance").toString());
    

    在调用 edgesIterator.next() 的那一刻,它会将光标移动到下一个元素。

    【讨论】:

    • layoutEdgesList&lt;HashMap&gt; - 它没有 entrySet()。据我们所知,虽然 OP 不需要使用listIterator(),但他们这样做的方式并没有错。
    【解决方案2】:

    在您的第一个 sn-p 中,您为循环的每次迭代调用了三次 edgesIterator.next(),我很确定您不想这样做。只是不要这样做:

    while (edgesIterator.hasNext()) {
        HashMap tmp = edgesIterator.next();
        tmpList.add(tmp.get("fromnode").toString());
        tmpList.add(tmp.get("tonode").toString());
        tmpList.add(tmp.get("distance").toString());
        String[] tmpStr = new String[tmpList.size()];
        returnArray.add(tmpList.toArray(tmpStr));
    }
    

    顺便说一句,如果您可以避免在 API 中使用原始类型,它通常会更简洁 - 我在这里谈论的是 HashMap 的使用。

    无论如何,我通常也会支持您的代码的第二个版本 - 除非您出于某种原因需要显式使用迭代器,否则让增强的 for 循环的语法糖自动为您完成。

    【讨论】:

    • 正如我所怀疑的......愚蠢的疏忽。这完全有道理 - 感谢您的及时回复!
    • 为什么建议避免使用原始类型,我可以将它们定义为 List&lt;HashMap&gt;List&lt;HashMap&lt;String&gt;&gt; 吗? (Netbeans 告诉我这是一个错误)
    • @CynePhoba12:原始类型会丢失类型信息,这意味着您必须到处转换或调用toString()。 (假设您的地图确实是Map&lt;String, String&gt;,您可以删除所有toString() 调用。)您需要为HashMap 指定两个类型参数,因为它有键和值——我个人会使用@ 987654330@ 而不是使 HashMap 明确。不知道更多,很难给出完整的代码,但我建议你尝试一下。
    猜你喜欢
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多