【问题标题】:Method remove() from LinkedList doesn't work [closed]LinkedList 中的方法 remove() 不起作用[关闭]
【发布时间】:2023-04-05 06:31:01
【问题描述】:

我正在尝试使这个简单的 Java 练习有效,但它没有,我不明白为什么。

这是我的代码:

public LinkedList<T> toSet()
{
    LinkedList<T> retList; 
    retList = lista;
    for(T elem1 : retList)
        for(T elem2 :retList)
        {
            if(retList.indexOf(elem1) == retList.indexOf(elem2)) 
                continue;
            else if(elem1.equals(elem2)) 
                retList.remove(elem1);
        }

    return retList;
}

该方法应删除列表中出现多次的元素。我已经用 eclipse 调试过了,发现retList.remove(elem1) 保持列表不变!

我的错误在哪里?

【问题讨论】:

  • 如果这有效,它会抛出一个 CommodificationException。考虑为循环使用迭代器。
  • 我建议你使用 Set。这将确保您一开始就没有重复。
  • @ValekHalfHeart:你的意思是ConcurrentModificationException
  • @jlordo 是的,当然,我的错。

标签: java


【解决方案1】:

你需要使用.clone()

LinkedList&lt;T&gt; retList = (LinkedList&lt;T&gt;) lista.clone();

此外,您需要在循环中使用迭代器从LinkedList 中删除。看到这个SO answer

【讨论】:

    【解决方案2】:

    简单的解决方案是使用 Set。在您的情况下,您可以使用。

    public Set<T> toSet() {
       return new LinkedHashSet<T>(lista);
    }
    

    【讨论】:

      【解决方案3】:

      你说这是一个练习,我在这里假设目标是生成一个表示集合的列表(不重复),而不使用 Set 集合。

      由于这是一个练习,我不会提供完整的代码,但我会提供与其他答案不同的方法。

      1. 新建一个空的Map&lt;T, Object&gt;
      2. 创建一个对象作为值,一个简单的new Object() 就足够了。
      3. 创建一个新的空LinkedList&lt;T&gt;。这是您将返回的列表。
      4. 从您的列表中创建一个Iterator&lt;T&gt;。这可以通过lista.iterator() 完成。
      5. 迭代你的列表,而你的迭代器hasNext()
        1. 使用迭代器的next() 检索当前元素。
        2. 检查您的地图是否为containsKey(),这是在5.1 中检索到的元素。
          • 如果是这样,则该元素是重复的,您不会将其添加到新列表中。 跳过。
          • 如果不是,则元素是新鲜的,因此您将 add() 指向新列表,并将 put() 在映射中作为键,指向在 2 中创建的占位符值。
        3. 重复5,即循环继续。
      6. 返回没有重复的新列表。

      【讨论】:

        【解决方案4】:

        在使用 for-each 循环迭代列表时,您不能从列表中删除项目。您应该改用迭代器:

        public LinkedList<T> toSet()
        {
            LinkedList<T> retList; 
            retList = lista;
            Iterator<T> iter1 = retList.iterator();
            int index1 = 0;
            while (iter1.hasNext()) {
                T elem1 = iter1.next();
                Iterator<T> iter2 = retList.iterator();
                int index2 = 0;
                while (iter2.hasNext())
                {
                    T elem2 = iter2.next();
                    if(index1 != index2 && elem1.equals(elem2)) 
                        iter2.remove();
                    index2++;
                }
                index1++;
            }
        
            return retList;
        }
        

        【讨论】:

        • 我同意使用迭代器,并且只从迭代器的remove 中删除。但是,就目前而言,我认为您的iter2 应该第一个while 中创建。否则,在外循环的第二次迭代中,iter2 不会hasNext
        • 另外,retList 不应该是一个新列表,而 iter1 不应该是原始列表的迭代器吗?从iter2 中删除元素不会导致iter1 引发异常吗?
        • @afsantos 你是对的iter2。谢谢!至于您的第二条评论,我不确定它是否会引发异常。我没有创建新列表,因为 OP 没有。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-04
        • 1970-01-01
        • 2014-01-26
        • 1970-01-01
        • 2016-12-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多