【问题标题】:Problems with removing objects from an arraylist in processing在处理中从数组列表中删除对象的问题
【发布时间】:2020-03-25 12:42:46
【问题描述】:

我对编程很陌生,我无法让它工作。 解释起来很复杂。基本上有一个粒子生成器可以生成一定数量的粒子。这些粒子需要相互交互,所以它们都有一个包含所有粒子的 ArrayList。但是,我不希望他们与自己交互,所以我想从他们自己的 ArrayList 中删除对象。存储类仍然拥有他自己的 Arraylist 中的所有对象。问题是当我试图让对象从它们的 Arraylist 中删除一个对象时,所有对象都被删除并且存储对象的 ArrayList 也是空的。我知道我不必这样做,但我真的很想知道它为什么不起作用,而且我认为如果它以这种方式工作比每次交互功能运行时必须跳过一个对象时更干净。 因为描述起来相当复杂,最好只看代码。 该代码仅包含重要的代码,它是一个简化版本。该行: l.remove(n); ,是把一切搞砸的那条线。

    G g;
    void setup()
    {size(1000, 600);
    g = new G(10);
    }
    void draw()
    {
      background(255);
      g.displayg();
      text(g.g.size(), 200, 200);
    }

将存储在 g 类中的第一个类

class D
    {
      int n;
      ArrayList<D> l = new ArrayList<D>();
      D(int input)
      {
        this.n = input;
      }
      void seTup(ArrayList<D> input)
      {
        l = input;
        l.remove(n); //if you delete this line, everything works
      }
      void display()
      {
        fill(0);
        text(this.n, 100+ 10* n, 100);
      }
    }

和存储类

class G
    { int number;
      ArrayList<D> g = new ArrayList<D>();
      G(int inputnumber)
      {this.number = inputnumber;
      for(int i =0; i < number; i++)
      {g.add(new D(i));

      }
      for(int i = g.size()-1; i>=0;i--)
      {
        D x =  g.get(i);
        x.seTup(g);
      }
      }
      void displayg()
      {
        for(D i : g)
        {//text(i.n, 100 + 5*i.n, 100);
          i.display();
        }
      }
    }

【问题讨论】:

  • 这可能是按索引删除的删除调用,而不是按整数对象?此外,每个粒子不需要由所有其他粒子组成。只需让处理所有这些元素的一个调用迭代所有这些元素,然后再次循环并检查第一个循环中的元素是否是第二个循环中的元素,如果是,则不要执行。
  • remove 调用确实按索引删除,但整数与 g ArrayList 中的索引匹配,该索引被复制到所有对象中,因此它应该删除正确的对象,并且每个对象只运行一次(我希望是这样)。出于某种原因,当您输入 0 或 n 时,仅删除调用不会出错

标签: java object arraylist processing


【解决方案1】:

您的问题可能是因为 Java 中的数组和 ArrayList 在您将它们传递给方法时会被浅拷贝。本质上,这意味着当您将 ArrayList 传递给一个方法时,而不是创建一个新的 ArrayList,它只是传递您当前 ArrayList 的内存位置,因此发生在方法内部的更改也会发生在方法之外。您从它自己的 ArrayList 中删除一个粒子,这会将其从顶级 ArrayList 中删除,并且由于您对每个粒子都执行此操作,因此顶级 ArrayList 将没有任何粒子。要解决这个问题,您需要创建一个看起来像这样的深拷贝方法:

ArrayList<d> deepCopy(ArrayList<d> original)
{
   ArrayList<d> copiedList = new ArrayList<d>();
   for(int i = 0; i < orginal.size(); i++)
   {
      copiedList.add(original.get(i);
   }
   return copiedList;
}

【讨论】:

  • 我认为你是对的,它似乎有效。当 d 对象获得更多数据时,例如具有移动位置,这些位置在复制列表中不会改变?还是会,因为它们仍然是同一个对象?
  • 很高兴听到。为了将来的参考,我相信 Java 中的大多数或所有对象都是浅拷贝的,尽管我不记得了,所以请留意这一点。默认情况下,我唯一可以保证被深度复制的是 int、bool、long 等原语。
  • 使用深拷贝,如果你改变一个位置,它只会改变你正在编辑的列表。如果您想在更新每个数组时更新它的位置,我最好的建议是,不要深度复制数组,而是使用 if 语句包围您访问数组的位置,该语句检查当前索引是否不等于索引您当前正在修改的 d。它看起来像这样“if(currentIndex != d.getIndex(){//code here}”可能有更好的方法来做到这一点,但我想不出。
  • 不错,值得注意的是可以使用 new ArrayList(Collection) 执行深度操作,即 new ArrayList(original);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2012-04-01
  • 1970-01-01
  • 2011-11-05
  • 2022-01-07
  • 2021-08-03
相关资源
最近更新 更多