Pergunta

I have a main 2d array of objects and I want to crop a portion of it. To be clear, I am trying to reference part of the main array and create a new object that corresponds to the specified area. So that if I change something in the cropped array it will change in the main array also. I am stuck in trying to figure out if arrays pass references to that object or the value. If i have an array

1,2,3
4,5,6

then I would be able to grab

2,3
5,6

and if I were to change it to

1,1
2,2

it would look like

1,1,1
4,2,2

This is the simple version of what i want to do.

Nenhuma solução correta

Outras dicas

I am stuck in trying to figure out if arrays pass references to that object or the value.

I'm not quite sure I understand your implicit question correctly, but Java arrays store their elements by value. That means an int array will store int elements while an Object array will store references to objects, and thus if you change the array element you'll change the reference to "point" to a differnt object while changing the object that is being referenced would not cause any direct change to the array.

As for your example:

You could create an object which holds a reference to the int[][] array (which btw is an object as well) and the offsets and size of the region you want to cover.

Then provide setters and getters which do the necessary index calculations and access the shared array, e.g. something like this:

//note that for simplicity's sake I'll omit a lot of code like constructors etc.
class Region {
  int[][] sharedArray;
  int xOffset;
  int yOffset;
  int width;
  int height;

  public int get(int x, int y) {
    //Note: you should check the array length and offsets to prevent IndexOutOfBoundsExceptions
    return sharedArray[x + xOffset][y + yOffset];
  }

  public set set(int x, int y, int value) {
    //Note: you should check the array length and offsets to prevent IndexOutOfBoundsExceptions
    sharedArray[x + xOffset][y + yOffset] = value;
  }
}

int[][] array = ...;
//define a 10x10 region starting at indices x = 2 and y = 4, e.g. it spans x = [2,11] and y = [4,13]
Region r = new Region(array, 2, 4, 10, 10); 

//retrieve the element at position 5/5 relative to the region
//or (5+2)/(5+4) = 7/9 in the shared array
int element = r.get( 5, 5 ); 

You could create a class, say CroppedArray, that provides the indirection. Something like;

public class CroppedArray {
int[][] theArray;
int x1, y1, x2, y2;

public CroppedArray(int[][] realArray,int x1,int y1,int x2,int y2) {
    theArray = realArray;
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
}
public int getCell(int i, int j) {
    return theArray[x1+i][y1+j];
}
public int setCell(int i, int j, int value) {
    return (theArray[x1+i][y1+j] = value);
}
 }

You would use it like

CroppedArray section = new CroppedArray(original,2,2,3,3);
 section.setValue(0,0,-1);
 if (original[2][2] != section.getValue(0,0)) { ... err.re  }

In java, everything is passed-by-value, however primitive types are stored as values, objects are stored as reference. If you try to do something with it, stored value is copied.

Look at the comments at each line :

static class MutableInteger {
    public int value;
}

public static void main(String[] args) {
    int[] arraya = new int[3];
    int[] arrayb = arraya; //reference is copied, they both referencing to the same array now
    arrayb[0] = 5;
    int value = arrayb[0]; //arrayb[i] is integer - primitive data type, hence the value is copied
    arrayb[0] = 3; //now arraya[0] and arrayb[0] are equal 3, "int value" is still 5

    MutableInteger[] arrayc = new MutableInteger[3];
    arrayc[0] = new MutableInteger();
    MutableInteger a = arrayc[0]; //MutableInteger is object, therefore is stored as reference in arrayc[0], reference is copied
    a.value = 5; //now the both, arrayc[0].value and "a.value" are equal 5
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top