How to create a class to handle multidimensional arraylist - java

During my search for info about multidimensional arraylist, I read that you could create a class to handle the multidimensional arraylist.
I'm doing a Android game similar to Bejeweled, and instead of using a common multidimensional grid, I guess this would be better!? I also has a list of all the sprite objects and I wonder if I can store and control all this objects with a multidimensional arraylist class?
But I'm not sure how a class would look like and how do I set and get values from the arraylists? Is there anyone who are interested to explain how it's working and show a simple code example? Thanks!
EDIT: I want to have objects in the arraylists like this example int grid[][] = new int[8][8]; but instead of integers, I want to have objects. And I wonder if it's possible to get and set values the same easy was like in the example I just showed?
EDIT 2: I have a grid 8x8 and that's why I'm using a array like [8][8], but I can only have values of type integers or booleans at each positions. I also have to use an arraylist to handle all the 64 objects that has a positions within this grid. Each object store it's position, both in the grid array and the position on the screen. I just wanted to make it a little bit simplier to handle and create a gird with multidimensional arrayList to both store the objects and have a grid? Possible or is there a better way to do this?

int size =8;
List<List<Integer>> list = new ArrayList<List<Integer>>(size);
for(int i=0; i<size; i++)
{
list.add(new ArrayList<Integer>());
}
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
Integer x = list.get(0).get(1); //access the 0,1 element
}
}
EDIT :
If you want to use a specific class. For ex: Node, you could use List<List<Node>> instead of List<List<Integer>> and then access it. You can then call any methods of the Node class as follows:
Node node = list.get(0).get(1); // access the Node at 0,1
node.getProperties();

There is no big difference between ArrayList and array.
Would say there are only 2 pros of ArrayList:
ability to dynamically change a size
adding new element at end of array, without need to look for first empty slot
And for multidimensional another pros is possibility to have different lengths for nested ArrayLists.
In Your case I think You don't need any of this so choose one You feel more comfortable, If You don't know how to make ArrayList of ArrayLists but know how to use array use them.
But just to answer Your question.
ArrayList<ArrayList<Object>> root = new ArrayList<ArrayList<Object>>();
root.add(new ArrayList<Object>());
root.add(new ArrayList<Object>());
root.add(new ArrayList<Object>());
root.add(new ArrayList<Object>());
root.get(1).set(1, Object); //puts new object at position 1,1
Object o = root.get(1).get(1); //gets object from position 1,1
With multidimensional array:
Object[][] grid = new Object[8][8];
grid[1][4] = new Object(); //set new object at position 1,4
grid[1][4].doSmth(); //calls method doSmth() of object stored at position 1,4
Object o = grid[1][4]; //gets object at position 1,4

List<List<Integer>> multiList = new ArrayList<List<Integer>>();
multiList.add(new ArrayList<Integer>());
Integer element = multi.get(0).get(0); // element at 0,0

First your start with defining your multi-dimensional arrayList
int size = 8;
List<List<YourClass>> 2dList = new ArrayList<List<YourClass>>(size);
then you initialize it
for(int rowIndex = 0; rowIndex < size; rowIndex++) {
List<YourClass> row = new ArrayList<YourClass>(size)
for(int columnIndex = 0; columnIndex < size; columnIndex++) {
row.add(new YourClass());
}
2dList.add(row);
}
now you have an sizexsize ArrayList with instances of your class
to access it:
2dList.get(rowIndex).get(columnIndex) // will return the YourClass-Object you placed there
if you want to replace the object on a certain position with another instance you need to remove the old object first:
2dList.get(rowIndex).remove(columnIndex);
2dList.get(rowIndex).add(columnIndex, newYourClass);

Related

Generic Array creation and null pointer errors

I have an array of linked list which runs parrallel to an ordered object array. If an extra element is entered into the object array i need to insert an extra element into the same space in the linked list.
I have this method as follows
public static LinkedList<User>[] insertElement (LinkedList<User>[]a, int index, User friend) {
LinkedList<User>[] bp = new LinkedList[nElems];
for (int i=0; i<index; i++){
bp[i]=a[i-1];
}
//index is the position in which i want to insert a new element
bp[index].add(friend);
for (int i=index+1; i<a.length; i++){
bp[i]=a[-1];
}
return bp;
}
When bp is initialised as shown I get a null pointer error
When it is initialised as:
LinkedList<User>[] bp = new LinkedList<User>[nElems];
I get a generic array creation error. What it the correct way to initialise this?
This line:
LinkedList<User>[] bp = new LinkedList[nElems];
..creates an array of null references to LinkedList<User>. You must initialize these before you use them:
LinkedList<User>[] bp = new LinkedList[nElems];
for (int i = 0; i < nElems; i++) {
bp[i] = new LinkedList<User>();
}
You have created an array of linked lists, but you haven't created any LinkedLists within the array.
You need to create the list in each slot of the array before you try and use it.
It seems unlikely that this is what you are actually trying to do though...you seem to be mixing up Arrays and Lists. Really you should use either Collections or Arrays, not mix the two together.
What I guess you are trying to do is having a ordered List of Users. If this is the case you can do this by just having a LinkedList and using
LinkedList<String> users = new LinkedList<>();
users.add( index, friend );
LinkedList.add automatically shifts all elements to the right.

Set size/dimensions of ArrayList<ArrayList<String>>

The problem
I have an ArrayList of ArrayLists. I am copying one over to the other, except in a different order (a rotation of the elements by 180°, but that's not important).
I have this generic code:
ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 5; c++) {
list.get(r).set(c, "an element from the other list");
}
}
I'm arbitrarily using sizes 4 for the number of rows and 5 for the number of columns.
However, this throws an index out of bounds error, obviously because I have no dimensions for the ArrayList<ArrayList<String>>.
I know that when creating an ArrayList, you can give it an initial capacity for a constructor parameter. However, I don't know how to apply that to this:
ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>();
This won't compile, but this is essentially what I want:
ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>(5)>(4);
My mediocre solution
To give the matrix some dimensions before I attempted to copy the list over, I just iterated for the number of rows I wanted and added a list of size of the number of columns I wanted to each row.
I used a regular array and converted it to an ArrayList just so that the elements would have a default value of null, and so would contribute to the size.
for (int r = 0; r < 4; r++) {
// list.add( new ArrayList<String>(5) ); // doesn't work
list.add( new ArrayList<String>( Arrays.asList(new String[5]) ) );
}
So that works for setting the size, because enough elements will be added to the matrix, but it's not the preferred solution.
The question
Is there any way to set the initial dimensions of an ArrayList of ArrayLists during the initialization? Or just something different that iterating and adding null values?
This works for me:
ArrayList<ArrayList<String>> list = new ArrayList<ArrayList<String>>(4);
for (int r = 0; r < 4; r++) {
ArrayList<String> ls = new ArrayList<String>(5);
ls.add("" + (r + 1));
list.add(ls);
}
for (ArrayList<String> ls : list) {
System.out.println(ls);
}
Note: do not confuse ArrayList#size(), current number of elements in the collection, with ArrayList#capacity, current maximum size of the collection (which cannot be accessed).
For more info, refer to: ArrayList(int):
Constructs an empty list with the specified initial capacity.
Note that using List<List<Whatever>> you're not creating a 2D dynamic array, you're creating a dynamic list which will contains dynamic lists, thus you must initialize every list by separate and add lists (from any size) into another list, and every list would have a dynamic size (despite the values they have). There's no 2d dynamic array nor dynamic array of arrays in plain Java, unless you create such class or import it from a third party library.
Looks like this structure would suit better for your case:
String[][] stringArrayOfArray = new String[4][5];
Another very odd way (not recommended) to accomplish what you want/need would be:
List<String>[] arrayOfList = new List[4];
for (int i = 0; i < arrayOfList.length; i++) {
arrayOfList[i] = new ArrayList<String>();
}

Java: 2D array of arraylists?

I am working on a sudoku solving program and I need an arraylist that holds the numbers 1 thru 9 for each of the squares on the 9x9 board. Each of these arraylists correspond to the possible numbers that could go in that square, if a number can not go in that square, it is removed from the list.
I want to be able to pull up the arraylist of the current square it is working on, like for example if I wanted to remove the number 7 from the arraylist corresponding to square (3,5)
arrayOfLists[3][5].remove(Integer.valueOf(7));
However I can't figure out how to do this. When I try to create the array I am getting this error on the line where I declare my array of arraylists
Cannot create a generic array of ArrayList
Here is my code:
//create arraylist
ArrayList<Integer> nums = new ArrayList<Integer>();
//fill arraylist with numbers 1-9
for (int i = 1; i < 10; i++) {
nums.add(i);
}
//create 9x9 array of arraylists
ArrayList<Integer>[][] array = new ArrayList<Integer>[9][9];
//fill each element of array with arraylist of numbers 1-9
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
array[i][j] = nums;
}
}
}
Am I doing this incorrectly or is it not possible to create an array of arraylists? If it is not possible, how should I do this then?
Anytime I see a list of lists, alarm bells start ringing. The situations where you actually want such a thing are rare indeed, and this is not one of them.
You've got a fixed board consisting of 9 fixed squares, columns and rows, each position of which may take a number 1-9.
Use an array for all of these concepts, because they are fixed in size and you need direct access to each element - collections offer no benefit and would be a hindrance. Use logic (possibly sets) to ensure numbers are used only once in each zone.
Use a bit field instead of an array list. That is, use an integer where bits 1-9 represent the possibilities of the numbers. Testing, adding, removing a single number is O(1), and it has a fixed memory size. Encapsulate the integer in its own object that knows the operations.
A few things:
1) In your for loop, array[i][j] = nums; This is going to result in the same object in each element of the array. If you call remove() on one element of the array, it's going to affect all the others. You want to build a separate list object for each element.
2) Program to interfaces; declare nums as a List as opposed to ArrayList.
3) Use a List of Lists as opposed to any array of Lists.
List<List<List<Integer>>> list = new ArrayList<List<List<Integer>>>();
for(int i = 0; i<9; i++){
List<List<Integer>> row = new ArrayList<List<Integer>>();
for(int j = 0; j<9; j++){
List<Integer> nums = new ArrayList<Integer>();
for (int k = 1; k < 10; k++) {
nums.add(i);
}
row.add(nums);
}
list.add(row);
}
// You can still get an element by index
int x = list.get(3).get(1).remove(6);
But this is kind of unwieldy. You might want to consider writing a class that represents the board. That way you'll at least have operations that better abstract this.
You could completely remove the use 2d stuff and keep a single list by giving each square a unique number from 1...81. So if you are working with 3,5 cell that means it's the 9*2+5 = 23rd item in the list. That will greatly simplify the list manipulation. You could use a single method to give the unique cell index given the (3,5) kind of reference
OK, I'm going to post this as an answer since it seems to work for me and I haven't yet seen any pitfalls.
private static class IntegerArrayList extends ArrayList<Integer> {
IntegerArrayList () { super(); }
IntegerArrayList (Collection<? extends Integer> c) { super(c); }
IntegerArrayList (int initialCapacity) { super(initialCapacity); }
}
Now you can say something like
IntegerArrayList[][] array = new IntegerArrayList[9][9];
and elements like array[1][2] will inherit all the ArrayList methods (array[1][2].remove(something) works fine). I made the class private static thinking you could nest it in some other class if that's the only place you'll use it, but you can make it public if you like. Also, I copied all three constructors from ArrayList; you could eliminate unneeded ones but I don't see a compelling reason to.
I think the issue is that new ArrayList<Integer>[9][9] is prohibited because it would create an array that wouldn't do type checking (because of "type erasure"). But I think adding your own non-generic type that inherits from ArrayList<Integer> restores the type safety.
But I'm not a generic expert, and it wouldn't surprise me if someone more knowledgeable than I spots a problem with this solution. But it seemed to work fine for me, with no compiler warnings about unchecked type stuff or anything.
(P.S. I'm posting this as a possible general solution to a problem that gets asked a lot. But in reality, for this particular problem, I might just use a fixed-size array of boolean instead of an ArrayList, like others, or I might even do bit-diddling on integers if speed is a real issue.)

How to remove element from an array

I have an array for example:
String [][] test = {{"a","1"},
{"b","1"},
{"c","1"}};
Can anyone tell me how to remove an element from the array. For example I want to remove item "b", so that the array looks like:
{{"a","1"},
{"c","1"}}
I can't find a way of doing it. What I have found here so far is not working for me :(
You cannot remove an element from an array. The size of a Java array is determined when the array is allocated, and cannot be changed. The best you can do is:
Assign null to the array at the relevant position; e.g.
test[1] = null;
This leaves you with the problem of dealing with the "holes" in the array where the null values are. (In some cases this is not a problem ... but in most cases it is.)
Create a new array with the element removed; e.g.
String[][] tmp = new String[test.length - 1][];
int j = 0;
for (int i = 0; i < test.length; i++) {
if (i != indexOfItemToRemove) {
tmp[j++] = test[i];
}
}
test = tmp;
The Apache Commons ArrayUtils class has some static methods that will do this more neatly (e.g. Object[] ArrayUtils.remove(Object[], int), but the fact remains that this approach creates a new array object.
A better approach would be to use a suitable Collection type. For instance, the ArrayList type has a method that allows you to remove the element at a given position.
There is no built-in way to "remove" items from a regular Java array.
What you want to use is an ArrayList.
You could set the entry in the array to null (test[0][1] = null;). However, "removing" the item such that the array will have one element less than before is not doable without recreating the array. If you plan to change data in the data structure regularly an ArrayList (or another Collection class depending on your needs) might be more convenient.
My solution is:
You cannot remove an element from an array => it's correct, but we can do something to change current array.
No need assign null to the array at the relevant position; e.g.
test[1] = null;
Create a new array with the element removed; e.g.
String[][] temp = new String[test.length - 1][];
Need to get index at string/array to remove: IndexToRemove
for (int i = 0; i < test.length-1; i++) {
if (i<IndexToRemove){
temp[i]=test[i];
}else if (i==IndexToRemove){
temp[i]=test[i+1];
}else {
temp[i]=test[i+1];
}
}
test = temp;
Hope it helpful!

How to filter an array in Java?

How can I filter an array in Java?
I have an array of objects, for example cars:
Class:
public class Car{
public int doors;
public Car(int d){
this.doors = d;
}
}
Use:
Car [] cars = new Cars[4];
cars[0] = new Car(3);
cars[1] = new Car(2);
cars[2] = new Car(4);
cars[3] = new Car(6);
Now I want to filter the array of cars, keeping only 4 doors and more:
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
//add cars[i] to a new array
}
}
How should I do this?
Before I did it with a Vector:
Vector subset = new Vector();
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
//add cars[i] to a new array
subset.addElement(cars[i]);
}
}
And then I would make a new array with the size of the Vector. Then I would loop over the vector again and fill the new array. I know this is a very large procedure for something simple.
I'm using J2ME.
EDIT: saw that ArrayList is not in J2ME, but based on documentation, it does have a Vector. If that Vector class is different than J2SE Vector (as this documentation indicates), then perhaps the following code would work:
Vector carList = new Vector();
for(int i = 0; i<cars.length; i++){
if(cars[i].doors > 4)
carList.addElement(cars[i]);
}
}
Car[] carArray = new Car[carList.size()];
carList.copyInto(carArray);
The most efficient way to do this--if the predicate you're filtering on is inexpensive and you're accessing it with a single thread--is usually to traverse the list twice:
public Car[] getFourDoors(Car[] all_cars) {
int n = 0;
for (Car c : all_cars) if (c.doorCount()==4) n++;
Car[] cars_4d = new Car[n];
n = 0;
for (Car c : all_cars) if (c.doorCount()==4) cars_4d[n++] = c;
return cars_4d;
}
This traverses the list twice and calls the test twice, but has no extra allocations or copying. The Vector-style methods traverse the list once, but allocates about twice the memory it needs (transiently) and copies every good element about twice. So if you are filtering a tiny fraction of the list (or performance isn't an issue, which very often it isn't), then the Vector method is good. Otherwise, the version above performs better.
If you really need a plain array as the result, I think your way is the way to go: you don't know the number of resulting elements before you filter, and you can't construct a new array without knowing the number of elements.
However, if you don't need thread-safety, consider using ArrayList instead of a Vector. It ought to be somewhat faster. Then use ArrayList's toArray method to get the array.
I can't see much wrong with your code. You could just stick with Vectors throughout though.
You could simplify the second part (where you copy the matching items into the new array) using Vector.copyInto(Object[]).
There's no direct way to remove elements from an array; its size is fixed. Whatever you do, you need to allocate a new array somehow.
If you want to avoid the minor memory overhead of allocating a Vector, another option would be to make two passes over your array. The first time, simply count the number of elements that you want to keep. Then allocate an array that size, and loop over your old array again, copying matching elements into the new array.
You can use System.arrayCopy():
Car[] cars = ...
int length = cars.length < 4 ? cars.length() : 4;
Car filter = new Car[4];
System.arrayCopy(cars, 0, filter, 0, length);
UPDATE: System.arrayCopy is available in Java ME API, unlike Vector.subList(). Thanks for the correction.
You will need to create a new array anyway.
Vector vector = new Vector(array.length);
for (int i = 0; i < array.length; i++) {
if (array[i].doors > 4) {
vector.add(array[i]);
}
}
Car[] result = new Car[vector.size()];
vector.copyInto(result);
This isn't quite efficient, though.

Categories