【问题标题】:Java ArrayList of ArrayList of integers not working rightJava ArrayList of ArrayList of integers 无法正常工作
【发布时间】:2023-04-05 10:21:01
【问题描述】:

我正在处理一个处理大量整数的项目,我决定使用一个名为 ALL_PIXELS 的 ArrayList>。我无法让我的 arrayList 或 Arraylists 中的值是唯一的。当我在 for 循环中使用一些基本测试检查代码时,一切正常,一旦退出 for 循环,子数组的所有值都是相同的,它们不应该是相同的。这是我的一些代码,也许有人可以帮助我。 我已经对 system.Out 语句进行了很多测试,并将它们注释掉。我发现问题在于我的 ArrayList ALL_PIXELS 在 for 循环中似乎没问题,但在 for 循环之后,其中的所有子数组都相同,这是一个问题。

package rmi.client;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ImageProducer;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.HashMap;

import rmi.Compute;
import rmi.RmiStarter;

public class StartComputeTaskMan extends RmiStarter {

// things for the Panel that i can't extend

private static JPanel mainPanel = new JPanel(); // this is what I'll add tocontentPane                                               
private static JPanel panel = new JPanel();
private JComponent[] allComponents = { panel };

final static int FRAME_WIDTH = 2000;
final static int FRAME_HEIGHT = 1500;
final static int MAX_ITERATION = 1000;
final static double ZOOM_FACTOR = 5;

final static double X_LEFT_BOUND = -2.5;
final static double X_RIGHT_BOUND = 1.5;
final static double Y_TOP_BOUND = 1.5;
final static double Y_BOTTOM_BOUND = -1.5;

final static BufferedImage IMAGE = new BufferedImage(FRAME_WIDTH,FRAME_HEIGHT, BufferedImage.TYPE_INT_RGB);
final static int[] COLORS = new int[MAX_ITERATION];
final static ArrayList<ArrayList<Integer>> ALL_PIXELS = new ArrayList<ArrayList<Integer>>();
ArrayList<HashMap<String, Double>> boundsHistory = new ArrayList<HashMap<String, Double>>();
int zoomNum = 0;

// end of global variables

// constructor
public StartComputeTaskMan() {
    super(PI.class);


    for (JComponent comp : allComponents) {
        mainPanel.add(comp);
    }// end for loop

    HashMap<String, Double> map = new HashMap<String, Double>();
    map.put("left", X_LEFT_BOUND);
    map.put("right", X_RIGHT_BOUND);
    map.put("top", Y_TOP_BOUND);
    map.put("bottom", Y_BOTTOM_BOUND);
    boundsHistory.add(map);

    for (int i = 0; i < MAX_ITERATION; i++) {
        COLORS[i] = Color.HSBtoRGB(i / 256f, 1, i / (i + 8f));
    }// end for loop
}// end constructor

public static JComponent getMainComponent() {
    return mainPanel;
}// end JComponent

private static void createAndShowGui() {

    // creating my JFrame only when I need it and where I need it
    JFrame frame = new JFrame("Mandelbrotset");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(getMainComponent());
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
    frame.setVisible(true);
    panel.setSize(FRAME_WIDTH, FRAME_HEIGHT);
    panel.setVisible(true);
    frame.add(panel);
}

@Override
public void doCustomRmiHandling() {
    try {
        System.setProperty("java.rmi.server.hostname", "172.31.98.63"); 
        System.out.println("Getting Registry");
        Registry registry = LocateRegistry.getRegistry("172.31.98.63"); 
        System.out.println("Getting Compute");
        try {
            Compute<Integer> compute = (Compute<Integer>) registry.lookup(Compute.SERVICE_NAME);            
        } catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}//end doCustomRmiHandling

public void doTask() {
    System.out.println("Getting Task");


    //why is this not making ALL_PIXELS unique for each row .............

    for (int i = 0; i < FRAME_HEIGHT; i++) {

        HashMap<String, Double> t = boundsHistory.get(zoomNum);
        PI task = new PI(i, t);
        //this is the problem. some where 
        ArrayList<Integer> temp = new ArrayList<Integer>();
        temp = task.execute();
        //System.out.println(temp);
        ALL_PIXELS.add(temp);
        //System.out.println(ALL_PIXELS.get(i));     //still unique here....WHYYYYYYY
        //System.out.println(temp);     //this shows that temp is a unique array each row

    }// end for loop    



    //why is all pixels seting the same vales to all of its sub arrays
    //System.out.println(ALL_PIXELS.get(3));
    //System.out.println(ALL_PIXELS.get(300));


    System.out.println("Computing");




}// end doTask



public double getScaledX(int x) {
    double returnValue = ((double) x / (double) FRAME_WIDTH)* (boundsHistory.get(zoomNum).get("right")
            - boundsHistory.get(zoomNum).get("left"))+ boundsHistory.get(zoomNum).get("left");      
    return returnValue;
}// end getscaledX

public double getScaledY(int y) {
    double returnValue = ((double) y / (double) FRAME_HEIGHT)* -(boundsHistory.get(zoomNum).get("top") 
            - boundsHistory.get(zoomNum).get("bottom")) + boundsHistory.get(zoomNum).get("top");    
    return returnValue;
}// end getscaledY

public static void main(String[] args) {
    createAndShowGui();//makes our GUI
    StartComputeTaskMan test = new StartComputeTaskMan();
    test.doTask();//fills in ALLPIXELS 

    //all of sub arrays are the same in all pixels



    //makeImage(test);//makes the buffered image
    //paintComponent(null);

}// end main

private static void makeImage(StartComputeTaskMan test) {
    for(int j=0; j<FRAME_HEIGHT;j++){
        for(int i=0;i<FRAME_WIDTH;i++){
            if(ALL_PIXELS.get(j).get(i)<MAX_ITERATION){
                IMAGE.setRGB(j,i,COLORS[ALL_PIXELS.get(j).get(i)-1]);
            }else{
                IMAGE.setRGB(j,i,0);

            }


        }//end nested for loop
    }//end for loop
}//end makeImage



private static void paintComponent(Graphics g){
    g.drawImage(IMAGE, 0, 0, FRAME_WIDTH, FRAME_HEIGHT,null);
}
}// end class

这是我的主要代码。我有的第二种方法是这个。所有这一切都有大约 7 个其他类使 RMI 成为可能。但是我遇到的这个问题不需要这些

package rmi.client;
                                                            //rmi client
import java.awt.image.BufferedImage;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;


import rmi.Task;

public class PI implements Task<BigDecimal>, Serializable {

    private static final long serialVersionUID = 3942967283733335029L;

    final static int FRAME_WIDTH = 2000;
    final static int FRAME_HEIGHT = 1500;
    final static int MAX_ITERATION = 1000;
    final static double ZOOM_FACTOR = 5;

    final static double X_LEFT_BOUND = -2.5;
    final static double X_RIGHT_BOUND = 1.5;
    final static double Y_TOP_BOUND = 1.5;
    final static double Y_BOTTOM_BOUND = -1.5;

    final static BufferedImage IMAGE = new BufferedImage(FRAME_WIDTH, FRAME_HEIGHT, BufferedImage.TYPE_INT_RGB);
    final static int[] COLORS = new int[MAX_ITERATION];
    //final static ArrayList<ArrayList<Integer>> ALL_PIXELS = new ArrayList<ArrayList<Integer>>(FRAME_HEIGHT);
    static ArrayList<HashMap<String, Double>> boundsHistory = new ArrayList<HashMap<String, Double>>();
    int zoomNum = 0;

    static ArrayList<Integer> rowList = new ArrayList<Integer>();

    static double scaledRow;
    static int row;
    static int frame_width = FRAME_HEIGHT;
    static int frame_height;
    static int max_iteration;
    static int[] colors;
    static HashMap<String, Double> bounds;
    static BufferedImage image;




public PI(int row, HashMap<String,Double> bounds){
        rowList.clear();//just to be safe
        this.row = row;
        this.bounds = bounds;
        scaledRow = getScaledY(row);

        frame_width = FRAME_WIDTH;
        frame_height = FRAME_HEIGHT;
        max_iteration = MAX_ITERATION;
        image = IMAGE;
        colors = COLORS;
    }

    /**
     * sending arrays to the rmi base and then to the server
     */
    public ArrayList<Integer> execute() {

        rowList = computePi(row);
        //System.out.println(rowList);
        return rowList;
    }
    //this is what is doing the work
    public static  ArrayList<Integer> computePi(int row) {



        for(int column = 0; column<frame_width; column++){
            double x0 = getScaledX(column);
            double y0 = getScaledY(row);
            double x = 0.0;
            double y = 0.0;
            int iteration = 0;

            while((x*x + y*y < 2*2) && iteration <max_iteration){
                double xtemp = x*x - y*y + x0;
                y = 2*x*y + y0;
                x = xtemp;
                iteration++;
                }
    //System.out.println("row number "+row + ": column number " + column+ ": " + " iterations "+iteration);
                if(iteration < max_iteration){

                    //image.setRGB(column,row,colors[iteration-1]);
                    rowList.add(iteration-1);
                    } else{
                        //image.setRGB(column,row,0);
                    rowList.add(0);
                    }
            }
        return rowList;

    }//end compute pi

        //MandelbrotSet2.ALL_PIXELS.add(row, rowList);

        public static double getScaledX(int x){
            double returnValue = ((double)x/(double)frame_width)*(bounds.get("right") - bounds.get("left")) + bounds.get("left");
            return returnValue;
        }

        public static double getScaledY(int y){
            double returnValue = ((double)y/(double)frame_height)*-(bounds.get("top") - bounds.get("bottom")) + bounds.get("top");
            return returnValue;
        }

        public void run() {
            computePi(row);
        }



    }

再一次,关于为什么 ALL_PIXELS 在 for 循环之外不是唯一的任何建议都会很好。我试图调试它,但我找不到我遇到问题的原因。

【问题讨论】:

  • 请提供问题的完整示例。我不知道boundsHistory 的类型是什么,也不知道定义PI 的类是什么样的。我建议您尝试删除所有无关的内容,并在您的问题中包含完整的上下文。
  • 感谢我去编辑上述帖子的建议。也感谢您的宝贵时间
  • 您为什么更喜欢 arraylist 而不是linkedhashmap?

标签: java arraylist


【解决方案1】:

尝试更改以下行:

    ArrayList<Integer> temp = new ArrayList<Integer>();
    temp = task.execute();
    //System.out.println(temp);
    ALL_PIXELS.add(temp);

到:

    ArrayList<Integer> temp = null;
    temp = task.execute();
    //System.out.println(temp);
    ALL_PIXELS.add(new ArrayList<Integer>(temp));

由于 PI 类的执行方法正在调用 computePi() 方法,该方法正在修改您添加到 ALL_PIXELS 列表中的数组列表引用。因此,每次都会修改相同的参考。 因此,在您将其添加到您的 ALL_PIXELS 列表时,请确保您有一个新的列表引用。

【讨论】:

  • 感谢您的帮助,这项工作完美地首次尝试。不久前,我在第一堂课中遇到过这个问题,但从来不知道出了什么问题。我也能够解决这个问题。非常感谢
猜你喜欢
  • 2023-04-01
  • 2019-05-05
  • 1970-01-01
  • 2023-03-23
  • 2017-02-19
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 2015-12-21
相关资源
最近更新 更多