initialize java array vs other initialization? - java

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.

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.

Purpose of new keyword in creating array in Java

I want to know why an array created in Java static even when we use the new keyword to define it.
From what I've read, the new keyword allocates a memory space in the heap whenever it is encountered during run time, so why give the size of the array at all during definition.
e.g. Why can't
int[] array1=new int[20];
simply be:
int[] array1=new int[];
I know that it does not grow automatically and we have ArrayList for that but then what is the use of keyword new in this? It could have been defined as int array1[20]; like we used to do it in C, C++ if it has to be static.
P.S. I know this is an amateurish question but I am an amateur, I tried to Google but couldn't find anything comprehensive.
This may be an amateurish question, but it is one of the best amateurish questions you could make.
In order for java to allow you to declare arrays without new, it would have to support an additional kind of data type, which would behave like a primitive in the sense that it would not require allocation, but it would be very much unlike a primitive in the sense that it would be of variable size. That would have immensely complicated the compiler and the JVM.
The approach taken by java is to provide the bare minimum and sufficient primitives in order to be able to get most things done efficiently, and let everything else be done using objects. That's why arrays are objects.
Also, you might be a bit confused about the meaning of "static" here. In C, "static" means "of file scope", that is, not visible by other object files. In C++ and in Java, "static" means "belongs to the class" rather than "belongs to instances of the class". So, the term "static" is not suitable for describing array allocation. "Fixed size" or "fixed, predefined size" would be more suitable terms.
Well, in Java everything is an object, including arrays (they have length and other data). Thats why you cannot use
int var[20];
In java that would be an int and the compiler would be confused. Instead by using this:
int[] var;
You are declaring that var is of type int[] (int array) so Java understands it.
Also in java the length of the array and other data are saved on the array, for this reason you don't have to declare size of array during declaration, instead when creating an array (using new) the data are saved.
Maybe there is a better reason that oracle may have answered already, but the fact that in Java everything is an object must have something to do with it. Java is quite specific about objects and types, unlike C where you have more freedom but everything is more loose (especially using pointers).
The main idea of the array data structure is that all its elements are located in the sequential row of memory cells. That is why you can not create array with variable size: it should be unbounbed space vector in memory for this purpose, which is impossible.
If you want change size of array, you should recreate it.
Since arrays are fixed-size they need to know how much memory to allocate at the time they are instantiated.
ArrayLists or other resizing data structures that internally use arrays to store data actually re-allocate larger arrays when their inner array data
structure fills up.
My understanding of OP's reasoning is:
new is used for allocating dynamic objects (which can grow like, ArrayList), but arrays are static (can't grow). So one of them is unnecessary: the new or the size of the array.
If that is the question, then the answer is simple:
Well, in Java new is necessary for every Object allocation, because in Java all objects are dynamically allocated.
Turns out that in Java, arrays are objects, different from C/C++ where they are not.
All of Java's variables are at most a single 64bit field. Either primitives like
integer (32bit)
long (64bit)
...
or references to Objects which depending on JVM / config / OS are 64 or 32 bit fields (but unlike 64bit primitives with atomicity guaranteed).
There is no such thing as C's int[20] "type". Neither is there C's static.
What int[] array = new int[20] boils down to is roughly
int* array = malloc(20 * sizeof(java_int))
Each time you see new in Java you can imagine a malloc and a call to the constructor method in case it's a real Object (not just an array). Each Object is more or less just a struct of a few primitives and more pointers.
The result is a giant network of relatively small structs pointing to other things. And the garbage collector's task is to free all the leaves that have fallen off the network.
And this is also the reason why you can say Java is copy by value: both primitives and pointers are always copied.
regarding static in Java: there is conceptually a struct per class that represents the static context of a class. That's the place where static instance variables are anchored. Non-static instance variables are anchored at with their own instance-struct
class Car {
static int[] forAllCars = new int[20];
Object perCar;
}
...
new Car();
translates very loosely (my C is terrible) to
struct Car-Static {
Object* forAllCars;
};
struct Car-Instance {
Object* perCar;
};
// .. class load time. Happens once and this is referenced from some root object so it can't get garbage collected
struct Car-Static *car_class = (struct Car-Static*) malloc(sizeof(Car-Static));
car_class->forAllCars = malloc(20 * 4);
// .. for every new Car();
struct Car-Instance *new_reference = (struct Car-Instance*) malloc(sizeof(Car-Instance));
new_reference.perCar = NULL; // all things get 0'd
new_reference->constructor();
// "new" essentially returns the "new_reference" then

Java array declaration without hard coding the size

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];

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).

Is there an expandable list of object references in Java?

In Java, we can always use an array to store object reference. Then we have an ArrayList or HashTable which is automatically expandable to store objects. But does anyone know a native way to have an auto-expandable array of object references?
Edit: What I mean is I want to know if the Java API has some class with the ability to store references to objects (but not storing the actual object like XXXList or HashTable do) AND the ability of auto-expansion.
Java arrays are, by their definition, fixed size. If you need auto-growth, you use XXXList classes.
EDIT - question has been clarified a bit
When I was first starting to learn Java (coming from a C and C++ background), this was probably one of the first things that tripped me up. Hopefully I can shed some light.
Unlike C++, Object arrays in Java do not store objects. They store object references.
In C++, if you declared something similar to:
String myStrings[10];
You would get 10 String objects. At this point, it would be perfectly legal to do something like println(myStrings[5].length); - you'd get '0' - the default constructor for String creates an empty string with length 0.
In Java, when you construct a new array, you get an empty container that can hold 10 String references. So the call:
String[] myStrings = new String[10];
println(myStringsp[5].length);
would throw a null pointer exception, because you haven't actually placed a String reference into the array yet.
If you are coming from a C++ background, think of new String[10] as being equivalent to new (String *)[10] from C++.
So, with that in mind, it should be fairly clear why ArrayList is the solution for an auto expanding array of objects (and in fact, ArrayList is implemented using simple arrays, with a growth algorithm built in that allocates new expanded arrays as needed and copies the content from the old to the new).
In practice, there are actually relatively few situations where we use arrays. If you are writing a container (something akin to ArrayList, or a BTree), then they are useful, or if you are doing a lot of low level byte manipulation - but at the level that most development occurs, using one of the Collections classes is by far the preferred technique.
All the classes implementing Collection are expandable and store only references: you don't store objects, you create them in some data space and only manipulate references to them, until they go out of scope without reference on them.
You can put a reference to an object in two or more Collections. That's how you can have sorted hash tables and such...
What do you mean by "native" way? If you want an expandable list f objects then you can use the ArrayList. With List collections you have the get(index) method that allows you to access objects in the list by index which gives you similar functionality to an array. Internally the ArrayList is implemented with an array and the ArrayList handles expanding it automatically for you.
Straight from the Array Java Tutorials on the sun webpage:
-> An array is a container object that holds a fixed number of values of a single type.
Because the size of the array is declared when it is created, there is actually no way to expand it afterwards. The whole purpose of declaring an array of a certain size is to only allocate as much memory as will likely be used when the program is executed. What you could do is declare a second array that is a function based on the size of the original, copy all of the original elements into it, and then add the necessary new elements (although this isn't very 'automatic' :) ). Otherwise, as you and a few others have mentioned, the List Collections is the most efficient way to go.
In Java, all object variables are references. So
Foo myFoo = new Foo();
Foo anotherFoo = myFoo;
means that both variables are referring to the same object, not to two separate copies. Likewise, when you put an object in a Collection, you are only storing a reference to the object. Therefore using ArrayList or similar is the correct way to have an automatically expanding piece of storage.
There's no first-class language construct that does that that I'm aware of, if that's what you're looking for.
It's not very efficient, but if you're just appending to an array, you can use Apache Commons ArrayUtils.add(). It returns a copy of the original array with the additional element in it.
if you can write your code in javascript, yes, you can do that. javascript arrays are sparse arrays. it will expand whichever way you want.
you can write
a[0] = 4;
a[1000] = 434;
a[888] = "a string";

Categories