Java 如何使用ArrayList.get()?

Java 如何使用ArrayList.get()?,java,processing,Java,Processing,我正在编写一个处理程序来制作一个三维散点图,人们可以使用PeasyCam在空间中旋转。数据从文本文件读入到PVectors的ArrayList中。整个代码如下所示。我不明白的是,需要在draw()中(反复)调用importTextfile(),这会大大降低速度。为什么我不能在setup()中调用它一次?通过draw()中的“println(pointsList)”,我可以看到,如果点列表前面没有importTextFile(),它会发生变化。有人能解释为什么吗 (更新:通过尝试构造一个最低限度的

我正在编写一个处理程序来制作一个三维散点图,人们可以使用PeasyCam在空间中旋转。数据从文本文件读入到PVectors的ArrayList中。整个代码如下所示。我不明白的是,需要在draw()中(反复)调用importTextfile(),这会大大降低速度。为什么我不能在setup()中调用它一次?通过draw()中的“println(pointsList)”,我可以看到,如果点列表前面没有importTextFile(),它会发生变化。有人能解释为什么吗

更新:通过尝试构造一个最低限度的工作示例,我现在看到问题是当我制作一个PVector V,然后将其写入以将其映射到显示窗口时。我仍然希望得到关于一个好的解决方法的反馈,包括在setup()期间调用importTextFile()。我使用什么来代替.get()所以我得到了Arraylist中内容的副本,而不是指向Arraylist中实际值的指针?)

代码如下:

import peasy.*;
PeasyCam cam;
ArrayList <PVector>pointList;   

int maxX = 0;
int maxY = 0;
int maxZ = 0;

int minX = 10000;
int minY = 10000;
int minZ = 10000;

int range = 0;

void setup() {
   size(500, 500, P3D);
   cam = new PeasyCam(this, width/2, width/2, width/2, 800);
   cam.setMinimumDistance(100);
   cam.setMaximumDistance(2000);
   pointList = new ArrayList();
   importTextFile();
   println(pointList);

 //Determine min and max along each axis
   for (int i=0; i < pointList.size(); i++) {
      PVector R = pointList.get(i);
      if (R.x > maxX) {
        maxX = (int)R.x;
      }
      if (R.x < minX) {
        minX = (int)R.x;
      }
      if (R.y > maxY) {
        maxY = (int)R.y;
      }
      if (R.y < minY) {
        minY = (int)R.y;
      }
      if (R.z > maxZ) {
        maxZ = (int)R.z;
      }
      if (R.z < minZ) {
        minZ = (int)R.z;
      }
   }

   if (maxX - minX > range) {
      range = maxX - minX;
   }
   if (maxY - minY > range) {
      range = maxY - minY;
   }
   if (maxZ - minZ > range) {
      range = maxZ - minZ;
   }
   println(pointList);
}

void draw() {
    //importTextFile();  Uncomment to make run properly
    println(pointList);
    background(255);
    stroke(0);
    strokeWeight(2);
    line(0, 0, 0, width, 0, 0);
    line(0, 0, 0, 0, width, 0);
    line(0, 0, 0, 0, 0, width);
    stroke(150);
    strokeWeight(1);
    for (int i=1; i<6; i++) {
      line(i*width/5, 0, 0, i*width/5, width, 0);
      line(0, i*width/5, 0, width, i*width/5, 0);
    }
    lights();
    noStroke();
    fill(255, 0, 0);
    sphereDetail(10);

    //**The problem is here**
    for (int i=0; i < pointList.size(); i++) {
      PVector V = pointList.get(i);
      V.x = map(V.x, minX-50, minX+range+50, 0, width);
      V.y = map(V.y, minY-50, minY+range+50, 0, width);
      V.z = map(V.z, minZ-50, minZ+range+50, 0, width);
      pushMatrix();
      translate(V.x, V.y, V.z);
      sphere(4);
      popMatrix();
    }
}

void importTextFile() {   
       String[] strLines = loadStrings("positions.txt");
       for (int i = 0; i < strLines.length; ++i) {
         String[] arrTokens = split(strLines[i], ',');      
         float xx = float(arrTokens[2]);                     
         float yy = float(arrTokens[1]);                    
         float zz = float(arrTokens[0]);                     
         pointList.add( new PVector(xx,zz,yy) );             
       }
    }
导入豌豆。*;
豌豆凸轮;
ArrayList点列表;
int max=0;
int-maxY=0;
int maxZ=0;
int minX=10000;
int minY=10000;
int minZ=10000;
int范围=0;
无效设置(){
尺寸(500,500,P3D);
凸轮=新的豌豆凸轮(这个,宽度/2,宽度/2,宽度/2800);
凸轮设置最小距离(100);
凸轮设定最大距离(2000);
pointList=新的ArrayList();
importTextFile();
println(点列表);
//沿每个轴确定最小值和最大值
对于(int i=0;imaxX){
maxX=(int)R.x;
}
如果(R.xmaxY){
maxY=(int)R.y;
}
if(R.ymaxZ){
maxZ=(int)R.z;
}
if(R.z范围){
范围=最大值-最小值;
}
如果(最大-最小>范围){
范围=最大-最小;
}
如果(最大-最小>范围){
范围=最大值-最小值;
}
println(点列表);
}
作废提款(){
//importTextFile();取消注释以使其正常运行
println(点列表);
背景(255);
冲程(0);
冲程重量(2);
线(0,0,0,宽度,0,0);
线(0,0,0,0,宽度,0);
行(0,0,0,0,0,0,宽度);
中风(150);
冲程重量(1);

对于(inti=1;i我用下面的代码修复了一些问题,但仍然对其他方式感兴趣

for (int i=0; i < pointList.size(); i++) {
  PVector V = pointList.get(i);
  PVector W = new PVector(0.0, 0.0, 0.0);
  W.x = map(V.x, minX-50, minX+range+50, 0, width);
  W.y = map(V.y, minY-50, minY+range+50, 0, width);
  W.z = map(V.z, minZ-50, minZ+range+50, 0, width);
  pushMatrix();
  translate(W.x, W.y, W.z);
  sphere(4);
  popMatrix();
}
for(int i=0;i
您可以继续进行重构,我不知道为什么在处理文档中会显示这种迭代ArrayList的方式,但这里有一个重构的方法:

float calcV (float n) {
  return map (n, minX-50, minX+range+50, 0, width);
}

for (PVector V: pointList) {
  pushMatrix();
    translate(calcV(V.x), calcV(V.y), calcV(V.z));
    sphere(4);
  popMatrix();
}

你可以考虑用pVoice作为一个字段来创建一个新的类,或者扩展pVoice。Daniel Shiffman经常使用这个模式。创建一个带有pVoto的位置,另一个用于速度的类,一个方法来调整每个帧的新位置,另一个将它画到屏幕上。这给了你很大的灵活性,而不必写一吨。循环,而不是一个循环,用于计算并显示ArrayList中的对象。

因为PVector是一个对象,所以当您执行
PVector V=pointList.get(i)
时,您会将pointList中特定元素的引用传递给V。它在内存中的地址。现在,V和pointList.get(数字)共享相同的内存地址。任何一个地址的更改都将同时更改这两个地址,因为它们是指向同一位置的两个不同指针。 但是,如果你这样做:

PVector V = new PVector(pointList.get(i).x, pointList.get(i).y, pointList.get(i).z);
V将是一个新对象,一切都将按照您的意愿运行,因为现在V有了自己的内存地址。poinList将保持不变。对于其他对象,例如数组,也一样,请尝试以下内容:

int[] one = new int[3];
int[] two = new int[3];

void setup(){
  one[0] = 0;
  one[1] = 1;
  one[2] = 2;

  print("one firstPrint -> \n");
  println(one);

  two = one;

  print("two firstPrint -> \n");
  println(two);

  two[2] = 4;

  // we didn't mean to change one, but...
  print("one secondPrint -> \n");
  println(one); 
}

你可能不小心在类中的其他地方更改了它。你能发布整个代码吗,这个函数看起来不错。+1用于询问其他解决方案