View Full Version : Java ArrayLists- construction parameters
phantomxprime
05-17-2006, 01:17 AM
hello!
I've been looking at the source code for the ArrayList class, and I found a constructor that allows you to make an ArrayList of a given length, ArrayList test = new ArrayList(int length);
(source code for ArrayList class) http://www.docjar.com/html/api/java/util/ArrayList.java.html
but whenever I try to use this constructor, a normal ArrayList is made, not the one with a length of 42 that I want.
So my question is: Does this constructor actually work?
I'd gladly use an array, but using an ArrayList is part of my assignment...
The code you provide a link to doesn't seem to be the code for ArrayList that is inherent to Java. The API for ArrayList specifies the default capacity is 10, where as the code you link to sets the default to 16. Are you using the code you link to or the implementation Java provides for you? (It may not make any difference to this problem however)
Are you using the ArrayList.size() method to determine if the length is 42? If so, you should find that the size method reports only how many items are in the current arraylist, not how many it can hold.
Thus, the following should always print 0:
ArrayList al = new ArrayList(42);
System.out.println(al.size());
ArrayList seems to act a lot like a Vector, which means it's capacity can grow, so my feeling is the initial capacity should be of minimal importance.
phantomxprime
05-17-2006, 02:45 AM
hmmm... I agree that initial value is usually of little importance in ArrayLists, but here's my.... problem? concern? issue?... something like that...
In my program, i need to use ArrayLists instead of arrays. However, I'm using a hash-type thing to put objects into the array, basing their index upon the originating button click and the click count of that button. I have 42 spaces, because there is a max of 42 objects. Upon mouseclick of a button, and on determining how many times that buttons been clicked, my program/applet should instantiate a new object and store that object into the ArrayList at a certain postion, based on which button was clicked and how many times its been clicked before.
Under normal circumstances, I'd prolly code my own Array class to hold my objects, but time is of the essence...
Thanks for ur help tho...
I think I understand what you want to do. You want to have an initial list size of 42 and insert into that list, but not necessarily in sequential order? Say, start with an empty list then maybe insert at index 5, then maybe index 35?
I don't have any previous knowledge of ArrayList, however, it doesn't seem to act as one would assume. Adding to the ArrayList seems to add to sequential indexs no matter what the "capacity" is suppose to be. The following code throws an IndexOutOfBounds exception even though it looks like it would work.
ArrayList al = new ArrayList(42);
Object obj = new Object();
Object obj2 = new Object();
al.add(0,obj);
al.add(5,obj2);
***IndexOutOfBoundsException: Index 5, Size 1
This seems to suggest that ArrayList doesn't actually create 42 spots in the list with each spot empty when it is constructed. Which seems contrary to how it looks like it works. Even though the capacity is suppose to be 42, it seems you can only insert into the list between index 0 and size + 1. Thus, inserting at index 5 when there's only 1 object in the list throws the OutOfBoundsException.
Again, I haven't used ArrayList in the past so maybe there's an easier way, but the following code seemed to do what I believe it is you want. With some caveats.
ArrayList al = new ArrayList();
Object obj = new Object();
Object obj2 = new Object();
for(int i = 0; i < 42; i++){
al.add(null);
}
al.set(0,obj);
al.set(5,obj2);
This will initially create a 42 node list with each node being "null". If we then treat each "null" as just a placeholder in the list and want to "insert" (really just overwrite a null object) nonsequentially into the list you could use the set method specifying the index in the list, and the obj to put at that index. (i.e al.set(5, obj2) )
A caveat to this method is that each node has an object at that index whether it's null or some other object. Thus, the size of the list will always include all of the remaining null objects in the list, and in this case al.size() would always return 42. Which is not really an accurate representation of how many "real" objects are in the list. As well, if you wanted to print out the contents of the list, you'd need to write your own toString method since the general al.toString would include all of the null objects when printing.
Not sure if that helps at all. Good luck.
Gox
phantomxprime
05-17-2006, 10:41 PM
O gawd I <3 u... That is exactly what I need to do. Thanks!
I dont need to reference the size at all in my applet, so that'll work.
thank you!
rpgfan3233
05-19-2006, 04:29 AM
Weird how they work. Oh well. To test if the list is empty (0 elements, despite even the default of 10), use the isEmpty() method:
// create an ArrayList with the default number of elements
ArrayList test = new ArrayList();
// check to see if it is empty
System.out.println(test.isEmpty());
ghell
05-19-2006, 11:34 AM
Collections in java have a capacity and a growth rate. Every time the capacity is reached it is increased. By default i believe the initial capacity is 10 and the growth rate doubles it every time it gets full. These are both allowed to be set for performance reasons.
Also note that you may want to use generics if you are using java1.5 or higher.
If you need a variable length array and only want to use it as an array you may be better off writing your own class (implement/extend the collections interfaces/classes if you wish) to wrap around an Object[].
A quick example i just threw together (haven't tested so you might want to play with it) is:public class GrowingArray<E>
{
private Object[] objArray;
public GrowingArray()
{
objArray = new Object[0];
}
public GrowingArray(int intCapacity)
{
objArray = new Object[intCapacity];
}
public int getCapacity()
{
return objArray.length;
}
public void setCapacity(int intNewCapacity)
{
if(intNewCapacity == objArray.length) return;
if(intNewCapacity >= 0)
{
Object[] objNewArray = new Object[intNewCapacity];
if(intNewCapacity < objArray.length)
System.arraycopy(objArray, 0, objNewArray, 0, intNewCapacity);
else
System.arraycopy(objArray, 0, objNewArray, 0, objArray.length);
objArray = objNewArray;
}
else
throw new ArrayIndexOutOfBoundsException(intNewCapacity);
}
public void setElement(int intIndex, E objToAdd)
{
// Your own capacity rules would go here to ensure no positive
// Indexes can be of bounds.
objArray[intIndex] = objToAdd;
}
public <T extends E> Object getElement(int intIndex)
{
return objArray[intIndex];
}
public int getFirstFreeIndex()
{
int intFirstFreeIndex = objArray.length;
for(int i = 0; i < objArray.length; i++)
if(objArray[i] == null)
{
intFirstFreeIndex = i;
break;
}
return intFirstFreeIndex;
}
public String toString()
{
if(objArray.length == 0)
return "[]";
StringBuilder sb = new StringBuilder("[");
for(int i = 0; i < objArray.length-1; i++)
{
sb.append(objArray[i]);
sb.append(", ");
}
sb.append(objArray[objArray.length-1]);
sb.append("]");
return sb.toString();
}
}If the getelement doesnt work you may wish to set its return type to just plain E and cast it before returning like this
return (E)objArray[intIndex];
vBulletin® v3.8.2, Copyright ©2000-2010, Jelsoft Enterprises Ltd.