Java array declaration without hard coding the size - java

How can I initialize an array of objects of a class in another class without hardcoding its size?

Use a List. The size does not need to be declared on creation of the List. The toArray() method will return an array representation of the list. There are multiple implementations you can use but the most popular tends to be ArrayList (though it is best to map the implementation to your particular situation).

Arrays have a fixed size after creation. The size doesn't need to be known at compile-time, but it does need to be known at creation time. For example:
public String[] createArray(int size) {
// Not hard-coded, but array is not expandable
return new String[size];
}
If you want a collection which can grow an shrink over time, look at the various List<E> implementations, such as ArrayList<E>.

Arrays are fixed in length. I would recommend using a Collection.
Here is an article on collections:
http://en.wikipedia.org/wiki/Java_collections_framework
With these, you can add elements by using an Add() command or something similar.
As mentioned in the previous answers, an ArrayList or List are collections.

Object[] will always be fixed size. If you need a variable length collection, try ArrayList, LinkedList, or one of the many others.
Pick the collection carefully, since they all have different performance aspects.

For mutable arrays other container objects are used.
When using a set of objects, an ArrayList or Vector object is used.
You can also store objects with an object key e.g. "Name" = "Ben" instead of [0] = "Ben".
Vector v = new Vector();
for(int i = 0; i < 100; i++){
Object o = new Object();
// init object
v.addElement(o);
}
for(int i = 0; i < 100; i++){
Object o = v.elementAt(i);
// manipulate object
}
Now you have an arbritairy list of object of undefined length.
Size found by using vector.size() method.
java.util package is required and part of J2SE 1.3 and higher.

As noted elsewhere, an array object has a fixed size. If there's some reason you must use an array, you can use one or both of these techniques:
Make it the larger than you need, leaving the unused
entries null. You may want to keep a "slotsUsed" variable.
When the array gets too small, make a bigger one and copy the
contents into it.
These are both used inside ArrayList.

You can create a new array and initialize it like this.
String[] strArray = {"Initialize","Array","Like","This"};
If you want an array with a dynamic size I would recommend using an ArrayList.

If you want an array of primitive instead of objects, you can use Trove4j. Otherwise use an ArrayList, or CopyOnWriteArrayList to wrap an array. There are other List implementations but these do not act like arrays for access time.

Sometimes it is useful, in case you know an upper bound of the objects your application needs,
to declare the size of an array as
static final int ARRAY_SIZE = 1000;
This goes near the beginning of the class so it can be easily changed.
In the main code instantiate the array with
Object[] objects = new Object[ARRAY_SIZE];
Also in case the array you want to use has the same size as another array consider using
Object[] objects = new Object[other_objects.length];

Related

Java Array size

I'm asking me if the initialization of array in Java is the same as C. In C you can't define the size of the array while the program is running. Is it possible in Java (or just right as concept)?
public int[] createArray(int size) {
return new int[size];
}
In my case I have to use an array and not an arraylist because I'm drawing a Polyline on a Panel
g.drawPolyline(xPoints[], yPoints[], n);
Thanks for help
You can't change array size once it's created,but you can use System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) to copy the value of the array to another bigger array,don't worry about its speed,because it's built-in function and implemented with JNI,so it's very fast
C does not have the fundamental concept of an "array" as Java does; in C, you'd
malloc(some_size * sizeof(one_element))
and affect it to a one_element * (of course, that is a gross description).
In Java, arrays are equally dynamically allocated; if you know the size, at runtime, then you can, for an array of SomeType and of size someSize do:
final SomeType[] myArray = new SomeType[someSize];
In essence, it's quite the same; including the fact that in both cases arrays are NOT resizable, but with a huge difference on what happens if you specify an invalid index:
in Java, this leads to an IndexOutOfBoundsException;
in C, this is undefined behavior.
All in all, apart from the consequences of using "arrays" incorrectly, what goes in C and what goes in Java only really differs by the syntax to create the array to begin with...
As others have mentioned, you cannot do this. But instead you can use ArrayList (or any other List) and where needed, convert it to simple array, like this:
ArrayList<String> arrayList = new ArrayList<>();
String strings[] = (String[])arrayList.toArray();
In C you can't define the size of the array while the program is running. Is it possible in Java (or just right as concept)?
Yes you can define the size of an array at runtime, just not redefine it. This will create an object on the heap with either enough space to hold the required number of primitives (in case of a primitive array) or object references (think of them as pointers).
If you want to redefine the size of an array you'd need to create a new one and copy the old (System.arraycopy() or Arrays.copyOf(...)).
In my case I have to use an array and not an arraylist because I'm drawing a Polyline on a Panel
Well, you could still use a list and call toArray(...) on it. This also is an example of creating an array at runtime.
Since you want to eventually call Graphics.drawPolyline(...) you'd have to either maintain two List<Integer> or preferably a List<Point> and construct the x and y arrays internally out of that list.

initialize java array vs other initialization?

I know that when I initialize a char array:
I have to
char[] b= new char[5];
or
char[] b= new char[5]({1,2,3,4,5});
why not like
ArrayList<Charset> list = new ArrayList<Charset>();
initialize array :
char[] b = new char[5](); ?
Why they are different? Is it one of java philosophical nature or some reasons behind it ?
If you've ever used C, then the answer is fairly simple. In C, the way you create arrays is by allocating a static length of memory on the stack that is large enough to contain the number of elements, and point to the first element with a pointer - or dynamic length of memory on the heap, and point to the first element with a pointer.
int a[5]; //stack, static allocation
int* a = (int*)malloc(sizeof(int)*5)); //heap, dynamic allocation
And in C++, the second version was changed to this, obviously because it's more obvious what is happening:
int* a = new int[5];
And they took this type of array creation over to Java.
int[] a = new int[5];
Arrays don't really work like typical objects, hence why even creating them and manipulating them with reflection uses a different Array class in order to manipulate the object. (see http://docs.oracle.com/javase/tutorial/reflect/special/arrayInstance.html )
ArrayLists are different, because they're just everyday classes like most things in java, so you initialize them with an actual constructor call:
List<T> = new ArrayList<T>();
Basically, arrays and classes just work in different ways.
That's is simply design of Java. ArrayList and Arrays are two different things. No need to be same declaration.
I guess the guys who created Java wanted to keep a syntax close to the C syntax. In Java, arrays are minimalist low-level objects, so their case is a bit particular.
ArrayList is a container, it's similar as Vector in C++, it can add and remove elements, but array can't change its size
Arrays and ArrayList are used for different purposes. If you need a fixed size collection of objects then go for array but if you need dynamically growing collection of objects then go for arraylist. In some way compiler need to know about what is your need, hence the syntax is different.

Regarding creation of dynamic array in java

Could you please advise how to create a dynamic array..!! A primitive array can be declared as
int[] myIntArray = new int[3];
But this time I know know the size of array is of 3 elements but what if I want to create a dynamic array how I will create that, Please advise.
An array has always to be initialised with a given size. Use a List if you wish to have a 'dynamic' collection and then convert to an array if needed. The array cannot be resized after instantiation whereas a List can (ignoring non modifiable lists).
You can instantiate an array using a variable, but once instantiated, the array will be stuck at that size.
int[] myArrayInt = new int[arraySizeVariable];
If you want something that is truly dynamic then I would suggest using an ArrayList instead.
List<Integer> myArrayList = new ArrayList<Integer>();
ArrayLists can grow and shrink dynamically:
ArrayList<Integer> list = new ArrayList<Integer>();
//...
list.add(5);
list.add(1);
//...
int index = list.indexOf(5);
list.remove(index);
use java.lang.reflect.Array
public static Object newInstance(Class<?> componentType, int length) {}
In Java you can have all sorts of dynamic groups of elements. The basic array [] is still going to be as static as it will in any other similar language, so you are going to want to use some implementation of the Collection.java interface.
The most basic one is a Vector which simply contains some objects, not necessarily of the same class, and will grow dynamically as you add or remove items from it. If you want them to be ordered then you can use an implementations of List.java. If you want the collection to be unique then you can use instances of Set.java.
public int[] createArray(int size){return new int[size];}
Well it's a dumb code. Creates array of size you want. It's not expandable once created. For that you need to expand manually by copying to a larger array when your old array is full. Or better, get it done by a collection called ArrayList, which doubles capacity when reaches to some threshold.
If you implement your own expandable array, it will be same as using ArrayList: see
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.

Java ArrayList<Double> IndexOutOfBoundsException Problem

I've got a Problem with ArrayList. I need it to store a result. Because I want to start with element n I tried to give the ArrayList a capacity with ensureCapacity(n+1) to use set(n,x) but I get an IndexOutOfBoundsException.
I tried to store n add(x) before the use of set and this works.
So I'd like to know why it doesn't work on my way and how to solve this because put n times a add(x) isn't a good style ;-)
When you change the capacity of an ArrayList it doesn't create any elements, it just reserves memory where there could be elements. You can check the size before and after adjusting the capacity and you will see that it does not change.
The purpose of changing the capacity is if you know in advance how many elements you will have, then you can avoid unnecessary repeated resizing as you add new elements, and you can avoid memory wastage from excess unused capacity.
If you don't like using your own loop and the list add method directly then there is another way. Create your ArrayList with the number of elements you want it directly like this:
final int MAX_ELEMENTS = 1000;
List<Integer> myList = new ArrayList<Integer>(
Collections.<Integer>nCopies(MAX_ELEMENTS, null));
Or, if you already have a list that you want to expand the size by n elements:
myList.addAll(Collections.<Integer>nCopies(n, null));
(Note, I assumed here that the list would be holding Integer objects, but you can change this to your custom type. If you are working with raw/pre-Java 5 types then just drop the generic declarations.)
As for your actual question: capacity != contents. An ArrayList internally has both a physical array and a count of what is actually in it. Increasing the capacity, changes the internal array so it can hold that many elements, however, the count does not change. You need to add elements to increase that count.
On the other hand, if you are just trying to set specific elements and know the maximum that you want to use, why not use an array directly? If you then need to pass this array to an API that takes Lists, then use Arrays.asList. The other classes could still change contents of your backing array but it would not be able to increase the size or capacity of it.
As others have answered, ensureCapacity() is just related to performance, is not frequently used by the common user.
From Bruce Eckel's Thinking in Java book:
In a private message, Joshua Bloch
wrote: "... I believe that we erred by
allowing implementation details (such
as hash table size and load factor)
into our APIs. The client should
perhaps tell us the maximum expected
size of a collection, and we should
take it from there. Clients can easily
do more harm than good by choosing
values for these parameters. As an
extreme example, consider Vector's
capacityIncrement. No one should ever
set this, and we shouldn't have
provided it. If you set it to any
non-zero value, the asymptotic cost of
a sequence of appends goes from linear
to quadratic. In other words, it
destroys your performance. Over time,
we're beginning to wise up about this
sort of thing. If you look at
IdentityHashMap, you'll see that it
has no low-level tuning parameters"
You are getting this exception because ensureCapacity() only makes sure that there is enough memory allocated for adding objects to an ArrayList, I believe this is in case you want to add multiple objects at once, without having to relocate memory.
To do what you want you would have to initiate the ArrayList with null elements first...
int n = 10; //capacity required
ArrayList foo = new ArrayList();
for( int i=0; i<=n; i++ ) {
foo.add(null);
}
Then you have objects in the List that you can reference via index and you wont receive the exception.
Perhaps you should rethink the choice of using List<Double>. It might be that a Map<Integer,Double> would be more appropriate if elements are to be added in an odd order.
Whether this is appropriate depends on knowledge about your usage that I don't have at the moment though.
Is the data structure eventually going to be completely filled, or is the data sparse?
what other people said about ensureCapacity() ...
you should write a class like DynamicArrayList extends ArrayList. then just overrride add(n,x) to do with for loop add(null) logic specified about.
ensureCapacity() has another purpose. It should be used in cases when you get to know the required size of the List after it has been constructed. If you know the size before it is constructor, just pass it as a an argument to the constructor.
In the former case use ensureCapacity() to save multiple copying of the backing array on each addition. However, using that method leaves the structure in a seemingly inconsistent state
the size of the backing array is increased
the size field on the ArrayList isn't.
This, however, is normal, since the capacity != size
Use the add(..) method, which is the only one that is increasing the size field:
ArrayList list = new ArrayList();
list.ensureCapacity(5); // this can be done with constructing new ArrayList(5)
for (int i = 0; i < list.size - 1; i ++) {
list.add(null);
}
list.add(yourObject);

Variable length (Dynamic) Arrays in Java

I was wondering how to initialise an integer array such that it's size and values change through out the execution of my program, any suggestions?
Yes: use ArrayList.
In Java, "normal" arrays are fixed-size. You have to give them a size and can't expand them or contract them. To change the size, you have to make a new array and copy the data you want - which is inefficient and a pain for you.
Fortunately, there are all kinds of built-in classes that implement common data structures, and other useful tools too. You'll want to check the Java 6 API for a full list of them.
One caveat: ArrayList can only hold objects (e.g. Integers), not primitives (e.g. ints). In MOST cases, autoboxing/autounboxing will take care of this for you silently, but you could get some weird behavior depending on what you're doing.
Arrays in Java are of fixed size. What you'd need is an ArrayList, one of a number of extremely valuable Collections available in Java.
Instead of
Integer[] ints = new Integer[x]
you use
List<Integer> ints = new ArrayList<Integer>();
Then to change the list you use ints.add(y) and ints.remove(z) amongst many other handy methods you can find in the appropriate Javadocs.
I strongly recommend studying the Collections classes available in Java as they are very powerful and give you a lot of builtin functionality that Java-newbies tend to try to rewrite themselves unnecessarily.
Arrays are fixed size once instantiated. You can use a List instead.
Autoboxing make a List usable similar to an array, you can put simply int-values into it:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
I disagree with the previous answers suggesting ArrayList, because ArrayList is not a Dynamic Array but a List backed by an array. The difference is that you cannot do the following:
ArrayList list = new ArrayList(4);
list.put(3,"Test");
It will give you an IndexOutOfBoundsException because there is no element at this position yet even though the backing array would permit such an addition. So you need to use a custom extendable Array implementation like suggested by #randy-lance
It is recommend to use List to deal with small scale size.
If you have a huge number of numbers, NEVER use List and autoboxing,
List< Integer> list
For every single int, a new Integer is auto created. You will find it getting slow when the size of the list increase. These Integers are unnecessary objects.
In this case, to use a estimated size would be better,
int[] array = new int[ESTIMATED_SIZE];
How about using a List instead? For example, ArrayList<integer>
You can't change the size of an array. You can, however, create a new array with the right size and copy the data from the old array to the new.
But your best option is to use IntList from jacarta commons. (here)
It works just like a List but takes less space and is more efficient than that, because it stores int's instead of storing wrapper objects over int's (that's what the Integer class is).

Categories