Array inside an Array - java

I'm making a program to get the midpoint of a line. However i'm running into a problem.
What i need to be able to do is have as many points as i want, and dimensions. However i have no idea how to do this
So let me give you an idea of what i want to do.
points[point][x]=1; points[point][y]=2; points[point][z]=3;
See what i'm getting at? This is what i currently have
public float[][] points={{}};
And when i want to write to it
for(int i=0; i<parts.length;i++){
points[currentPoint][i]=Float.valueOf(parts[i]);
}
java.lang.ArrayIndexOutOfBoundsException: 0
So how can i do this?

public float[][] points={{}};
This creates an empty two dimensional array. Hence, the ArrayIndexOutOfBoundsException.
If you want to create an array to hold 6 points and 3 dimensions then you have to allocate it:
public float[][] points = new float[6][3];
However, I would reconsider your design. If you would like to go more object oriented way than you would probably like to have a class for line as well as for point. For example:
class Line {
private final Point startPoint;
private final Point endPoint;
Line(Point startPoint, Point endPoint) {
this.startPoint = startPoint;
this.endPoint = endPoint;
final int startPointDimensions = startPoint.getDimensions().size();
final int endPointDimensions = endPoint.getDimensions().size();
if (startPointDimensions != endPointDimensions) {
throw new RuntimeException("Points that form a line must have the same dimension! " +
"Start point dimension: " + startPointDimensions +
"End point dimension: " + endPointDimensions);
}
}
public Point midpoint() {
// your code goes here
}
}
class Point {
private final List<Float> dimensions;
Point(List<Float> dimension) {
dimensions = dimension;
}
public List<Float> getDimensions() {
return dimensions;
}
}
You can read more about lists in the oracle's documentation. I would prefer lists to arrays if you do not know up front how many dimensions you want to support or if you want to support different number of dimensions.

Use this to create a 3x3 2-D array and initialize all values to 0:
public float points[][] = new float[3][3];
And this to iterate through the array and set values:
for (int j=0; j<3; j++) {
for (int i=0; i<3; i++) {
points[j][i] = 42; //Or whatever
}
}

Related

How do I remove random object inside array? New to java

I'm doing a small project where I have two different types of ball objects inside a bag array and I want to take two random objects from that bag. The problem that I am having is removing the objects from that bag array. I am succeeding to take two random objects but it takes in their position in the bag array and I don't really know how to remove objects from that bag array.
public class Bag {
public static void main(String[] args) {
Balls whiteBalls = new Balls("White");
Balls blackBalls = new Balls("Black");
Balls[] objArray;
whiteBalls.setAmount(16);
blackBalls.setAmount(20);
int totalBalls = whiteBalls.getAmount() + blackBalls.getAmount();
// Create two arrays that hold white and black balls together.
Balls[] white = new Balls[whiteBalls.getAmount()];
Balls[] black = new Balls[blackBalls.getAmount()];
// Adding white balls into array "white".
for (int i = 0; i < whiteBalls.getAmount(); i++) {
white[i] = new Balls("White");
} // Adding black balls into array "black"
for (int i = 0; i < blackBalls.getAmount(); i++) {
black[i] = new Balls("Black");
}
Balls[] bag = new Balls[totalBalls]; // Making a bag which holds all the balls.
// Copy's both arrays and fills up array "bag".
System.arraycopy(white, 0, bag, 0, whiteBalls.getAmount());
System.arraycopy(black, 0, bag, 16, blackBalls.getAmount());
//System.out.println(Arrays.toString(bag));
int count = 0;
Random rnd = new Random();
String[] colours = new String[]{"White", "Black"};
while(bag.length != 1){ // Depending on what colour the balls are either black ball or white ball is placed back into the bag.
count++;
int select1 = rnd.nextInt(colours.length);
int select2 = rnd.nextInt(colours.length);
while(white.length != 0 || black.length != 0){
if(select1 == 0 && select2 == 0){
System.out.println("Both are the same colour. " + select1 + " " + select2);
}
}
}
}
}
The other problem that I am running into is in my other class which balls one method 'getColour()' doesn't want to work for some reason.
public class Balls {
private String colour;
private int amount;
public Balls(String type) {
colour = type;
}
public String getColour() {
return colour;
}
public void changeAmount(int num){
this.setAmount(num);
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String toString() {
return colour;
}
}
Any feedback is appreciated. Thank you for reading and thanks in advance.
I'd recommend you using an ArrayList, as it provides methods to remove elements from within the list (be aware, as this can be quite costly in a large array). The remove() method can take an index of the object to remove or the object to remove itself, as the method is overloaded. Be aware, as storing to int's that hold the index of the element in the bag that should be removed, can result in unexpected results, as it can be, that this index points to the wrong object after you removed an object after you stored the indices.So, I hope this answer helps you.

Cloning an object and its inside arrays in Java DIY

I am trying to clone an object without using any library.
The object has other objects/arrays/matrixes in it.
So I developed some methods to clone those as well.
They are working fine when I am cloning arrays/matrixes that are not inside the object.
These are the methods:
public static int[] cloneArray(int[] array){
int i = 0;
int[] clone = new int[array.length];
while (i < array.length){
clone[i] = array[i];
i++;
}
return clone;
}
public static int[][] cloneMatrix(int[][] matrix){
int[][] clone = new int[matrix.length][matrix[0].length];
for (int i = 0;i<matrix.length;i++)
for(int j = 0;j<matrix[0].length;j++)
clone[i][j] = matrix[i][j];
return clone;
}
However, when I want to clone an object, the references of the array/matrix stay the same, as you can check in the output on the bottom of the post.
This is the constructor I have:
public State(int parentStateID, int stateID, int[][] board, int[] pieces, int points, int acquiredPoints){
State.parentStateID = parentStateID;
State.stateID = stateID;
State.currentBoard = cloneMatrix(board); //here takes place the matrix cloning
State.currentPieces = cloneArray(pieces); //here takes place the array cloning
State.totalPoints = points;
State.acquiredPoints = acquiredPoints;
}
And this is the cloning method:
public static State cloneState(State state){
int[][] currentBoard = state.getCurrentBoard();
int[] currentPieces = state.getCurrentPieces();
int totalPoints = state.getTotalPoints();
int acquiredPoints = state.getAcquiredPoints();
int parentStateID = state.getParentStateID();
int stateID = state.getStateID();
State clone = new State(parentStateID,
stateID,
currentBoard,
currentPieces,
totalPoints,
acquiredPoints);
return clone;
}
To better visualize the output, here are the arrays and matrix:
public static int piecesList[] = {1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
public static int piecesList2[] = {2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
public static int piecesList3[] = {3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
private static int[][] map = {{0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14},{15,16,17,18,19},{20,21,22,23,24}};
Here is the verification code:
int[][] state2 = cloneMatrix(map);
state2[0][0] = 1;
System.out.println("map.original " + map[0][0]);
System.out.println("map.clone " + state2[0][0]);
System.out.println("");
System.out.println("");
int[] pc = cloneArray(piecesList);
pc[24] = 1;
System.out.println("pieces.original " + piecesList[24]);
System.out.println("pieces.clone " + pc[24]);
System.out.println("");
System.out.println("");
State newState = setFirstState();
State clonedState = cloneState(newState);
clonedState.setCurrentPieces(piecesList2);
System.out.println("newState.pieceslist: "+newState.getCurrentPieces()[0]);
System.out.println("clonedState.pieceslist: "+clonedState.getCurrentPieces()[0]);
System.out.println("piecesList.original: "+piecesList[0]);
System.out.println("");
newState.setCurrentPieces(piecesList3);
System.out.println("newState.pieceslist: "+newState.getCurrentPieces()[0]);
System.out.println("clonedState.pieceslist: "+clonedState.getCurrentPieces()[0]);
System.out.println("piecesList.original: "+piecesList[0]);
And here is the output:
map.original 0
map.clone 1
pieces.original -1
pieces.clone 1
//as you can check in the next two cases, the change takes effect in both the original state, and the cloned state
newState.pieceslist: 2
clonedState.pieceslist: 2
piecesList.array variable: 1
newState.pieceslist: 3
clonedState.pieceslist: 3
piecesList.array variable: 1
Been trying to solve this issue for over 12 hours, without much success...
I have tried libraries as well as serialization with no success...
Help is much appreciated!
The problem with your code is that the fields (not shown) obviously are static, as can be told from your constructor:
public State(int parentStateID, int stateID, int[][] board, int[] pieces, int points, int acquiredPoints){
State.parentStateID = parentStateID;
State.stateID = stateID;
State.currentBoard = cloneMatrix(board); //here takes place the matrix cloning
State.currentPieces = cloneArray(pieces); //here takes place the array cloning
State.totalPoints = points;
State.acquiredPoints = acquiredPoints;
}
The constructor should instead read like this:
public State(int parentStateID, int stateID, int[][] board, int[] pieces, int points, int acquiredPoints){
this.parentStateID = parentStateID;
this.stateID = stateID;
this.currentBoard = cloneMatrix(board); //here takes place the matrix cloning
this.currentPieces = cloneArray(pieces); //here takes place the array cloning
this.totalPoints = points;
this.acquiredPoints = acquiredPoints;
}
A field which is static exists only once per class. A field which is not static exists once per each object constructed from that class (or any subclass). Because of that, you actually created objects which are empty, and whatever you thought you would store in the object you actually stored in the class, thus sharing the same data among all objects.
As a rule of thumb, you usually do not want any static non-final fields in your classes. Exceptions apply, but they're rare and mostly limited to a few tiny bootstrapping things in frameworks.

doubling Array size if full

I have an array of objects. When the array fills up, I want to make a new array twice as large as the old one, and transfer all the elements over. I'm doing something wrong, I think its something to do with I'm not creating the correct reference to the new array. Here's my code, any help figuring this out would be appreciated.
private int DIRECTORY_SIZE = 6;
Entry [] directory = new Entry[DIRECTORY_SIZE];
private int numberOfElements = 0;
public int getNumOfElements(){
return numberOfElements;
}
public void setDirectorySize(int size){
DIRECTORY_SIZE = size;
}
public int getDirectorySize(){
return DIRECTORY_SIZE;
}
public void addEntry(String surname, String initial, String num) {
// TODO add an entry to an array, also increments numberOfElements variable tracking whats in array
if(getNumOfElements() == getDirectorySize()){ // if array is full
doubleArraySize(); // put temp values into new bigger directory array
}
int i = findFreeLocation();
directory[i] = new Entry(surname, initial, num);
numberOfElements++;
}
private void doubleArraySize(){
Entry[] temp = new Entry[DIRECTORY_SIZE]; //make new temp array same size as old one
for(int i = 0; i < DIRECTORY_SIZE ; i++){
temp[i] = directory[i]; // cycle through array putting all values into temp
// works up to here
}
setDirectorySize(DIRECTORY_SIZE*2); // double size of array
Entry[] directory = new Entry[DIRECTORY_SIZE]; // create new, double size directory array
for(int i = 0; i < temp.length ; i++){
directory[i] = temp[i];
}
}
private int findFreeLocation() {
int i;
for (i = 0; i < DIRECTORY_SIZE; i++)
{
if(directory[i] == null)
{
break;
}
}
return i;
}
In doubleArraySize() function , this is the issue :
Entry[] directory = new Entry[DIRECTORY_SIZE];
// you are not assigning it to the class attribute directory
// instead you are creating a local array directory
Make the following change :
this.directory = new Entry[DIRECTORY_SIZE];
// this will assign the newly created array to the class attribute
Note : I personally prefer to use this pointer to refer to class attributes so that it makes my code more readable, and its clear to everyone that the variable in question is a class attribute rather than local variable.
**SIZE has already double by this point. No need to multiple by 2
I remember doing something exactly like this when I was making a Vector ADT. However, I used instance variables instead of methods in my code for element number and the capacity. I definitely didn't initialize a Vector inside a method for a Vector.
setDirectorySize(DIRECTORY_SIZE*2); // double size of array
Entry[] directory = new Entry[DIRECTORY_SIZE]; // create new, double size directory array
Isn't DIRECTORY_SIZE an instance variable? Because if it is, I don't think you can initialize an object using an instance variable from the object you are overwriting.
Putting my code into your context, it would look something like this:
private void doubleDirectorySize()
{
Entry[] new_array = new Entry[new_directory_size*2];
for (int i = 0; i < directory_size; i++)
{
new_array[i]= directory[i];
}
directory= new_array;
}
This only works if directory was initialized to null, though, moving the pointer directory to the new array.

ArrayList not adding objects?

I have a piece of code:
public void setBoardMemberPosition() {
int[] position = null;
do{
positionX = RandomNumberGenerator.generateRandomNumber(Board.DIMENSION);
positionY = RandomNumberGenerator.generateRandomNumber(Board.DIMENSION);
position = new int[] { positionX, positionY };
} while(checkIfPositionIsOccupied(position));
board.setElementAt(positionX, positionY, name);
storedMembers.add(position);
}
Can someone explain to me why the elements are not being added to the list, where:
private ArrayList<int[]> storedMembers = new ArrayList<int[]>();is a Class variable and:checkIfPositionIsOccupied(position) returns true/false
if (storedMembers.contains(position))
i have a feeling its something to do with the do while, ive debugged it with no luck.
If you want to add the array position to the ArrayList on each iteration, your add() call must be inside the loop:
do {
// ...
storedMembers.add(position);
} while(...);
Edit:
for (int i = 0; i < storedMembers.size(); i ++)
// ...
if (!checkIfPositionIsOccupied(position))
storedMembers.add(position);
}
Because you don't add in your while loop anything to the list?!

How does one access an ArrayList of ArrayLists? (Generics?)

I'm trying to create a table class, who's rows and columns may expand or shrink, to store ints and strings as a first Java project. The data structure I'm trying to use to represent the table is an ArrayList of ArrayLists, where the initial array's elements all point to a new array list - so the initial array kind of serves as an entrance into rows. This would be a picture of how I have it in my mind, for reference:
The problem I'm having is accessing the inner ArrayLists. I've been reading a bit of documentation, and I can't seem to understand the big issue with why I'm not able to access the inner lists. Some code here:
import java.util.ArrayList;
public class Table {
private int length, width;
private ArrayList newTable;
public Table() {
this.length = this.width = 0;
}
/**
* Testing a few functions
*/
public static void main(String[] args) {
// Just testing a few functions.
Table list1 = new Table();
list1.createTable(4, 4);
list1.displayRow(1);
list1.displayColumn(1);
System.out.println("displayColumn done!");
list1.displayEntireTable();
}
public void createTable(int tableLength, int tableWidth) {
length = tableLength;
width = tableWidth;
this.newTable = new ArrayList();
for (int i = 0; i < tableWidth; i++) {
this.newTable.add(new ArrayList(tableLength));
}
}
public void displayRow(int row) {
System.out.println(this.newTable.get(row));
}
/**
* This function displays the column of the table. Still work which
* needs to be done here.
* #param column
*/
public void displayColumn(int column) {
if (this.newTable.size() >= column) {
for (int i = 0; i < this.newTable.size(); i++) {
// This doesn't work.
System.out.println(this.newTable.get(i).get(column));
}
}
}
public void displayEntireTable() {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println(this.newTable.get(i));
}
}
}
I'm suspicious that the problem may rely the lack of use in generics, which I'm not quite as familiar with yet as I would like to be. So my question to you, stackoverflow, is whether this data structure - an ArrayList of ArrayLists - is even possible, and if so, where lays my problem?
I think the problem is that you misunderstood the semantics of the new ArrayList(tableLength) call: it does not create an array list of tableLength elements; rather, it creates an ArrayList with the initial capacity enough to hold at least tableLength elements.
I am not sure what kind of elements you are planning to add to your ArrayList of ArrayLists, but here is one way to test your code that creates a two-dimensional ArrayList:
for (int i = 0; i < tableWidth; i++) {
ArrayList toAdd = new ArrayList(tableLength);
for (int j = 0; j != tableLength ; j++) {
toAdd.add(new Integer(i*tableLength +j));
}
this.newTable.add(toAdd);
}
Using Java 1.7 generics improvements:
import java.util.ArrayList;
import java.util.List;
public class Table {
private int length, width;
private List<List<String>> newTable;
public Table() {
this.length = this.width = 0;
}
/**
* Testing a few functions
*/
public static void main(String[] args) {
// Just testing a few functions.
Table list1 = new Table();
list1.createTable(4, 4);
list1.displayRow(1);
System.out.println("displayRow done!");
list1.displayColumn(1);
System.out.println("displayColumn done!");
list1.displayEntireTable();
System.out.println("displayEntireTable done!");
}
public void createTable(int tableLength, int tableWidth) {
length = tableLength;
width = tableWidth;
//by java 1.7 diamond feature, some generics can be hidden
this.newTable = new ArrayList<>();
for (int i = 0; i < tableWidth; i++) {
List<String> columns = new ArrayList<>();
for (int j = 0; j < tableLength; j++) {
columns.add(new String("test"));
} //added here
this.newTable.add(columns);
}
}
public void displayRow(int row) {
System.out.println(this.newTable.get(row));
}
/**
* This function displays the column of the table. Still work which
* needs to be done here.
* #param column
*/
public void displayColumn(int column) {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println("[" + this.newTable.get(i).get(column) + "]");
}
}
public void displayEntireTable() {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println(this.newTable.get(i));
}
}
}
Sure it's possible, and I suspect your issues are related to generics, actually -- if you don't use generics, you'll have to do a bunch of casts, which may appear to you as if it just doesn't work.
I'd write this as something like
List<List<Object>> table;
and then I'd add rows by doing table.add(new ArrayList<Object>()), and access elements with table.get(i).get(j).
First of all, what is your real problem? You don't add any data into the inner ArrayLists, so they are empty.
On the other hand, it is better if you create an object for a row, and store these objects in an arraylist.
Change your code that doesn't work to:
System.out.println(((ArrayList) this.newTable.get(i)).get(column));
ArrayList in ArrayList is certainly possibly.
And it is certainly not generics that prohibits you.
Generics is only a compile time check for mistakes and has nothing to do with it. You can complete leave it out, not advised as the probability for class cast exceptions due too mistakes is far larger.
Explanation. The compiler don't knows your ArrayList contains an ArrayList so it doesn't recognize the get method as it trys to invoke it on Object and not ArrayList. So the solution is to cast it if you wan't to use it without generics. However I would recomend to use generics and define your List like this.
private List<List<String> newTable;
Notice how I used List and not ArrayList. Typically your left hand assignment contains an Interface and the right hand an concrete class like ArrayList.

Categories