I thought I'm pretty experienced in java, but it seems that's not really the case, I just noticed something yesterday, something I used before but never really realised what it did. I googled but didn't find the answer to my question.
If I declare an int array, and use Array's static sort function to sort my array, I just need to type
Arrays.sort( numbers );
Instead of
numbers = Array.sort( numbers );
This might look very easy in C and C++ because you can use pointers there. So what I'm wondering is, how is this done? Is it an advantage sun has, or am I completely senseless here?
Pointers exist in java - all non primitive variables are pointers in java, aka references.
THey do not support the same set of operations as pointers in C tho - they are essentially opaque to the user of the language.
The reason Arrays.sort(array) works is because array is a "pointer", which allows the sort() function access to the memory location that the array variable points to.
Now, why doesn't:
void swap (Integer a, Integer b) {
Integer tmp = a;
a = b;
b = tmp;
}
work if you did
Integer x = 1;
Integer y = 2;
swap(x,y);
Its because java passes by value (which is a concept distinct from pointers). The pointer to 1 is given to swap(), not as the value of the variable x (which is a memory address, or pointer). Thus, manipulating the arguments in swap() does nothing to effect the variable x.
First, this belongs on StackOverflow. Second, you want to read the article Java is Pass-by-Value, Dammit!
It sorts the array in-place.
The sort method receives a reference to the number array (which is an object), and changes the values inside the array! No new array-object is created, it is thus good enough to just pass it to the sort function.
PS: all source code of Java is open, you can go and read the sources of the sort function yourself. You'll see, there be no magic. If Java is installed properly on your system, there should be a src.zip in the Java home folder.
I assume numbers is an int-array, and all arrays in Java are objects. So sort is passed a reference to numbers, and it can sort them in place.
This question should be migrated to Stack Overflow. The fact that Java has a NullPointerException class should give you a strong hint as to whether Java uses pointers behing the scenes.
Related
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
1) Can I create a link list in C with out using pointers (and without using structure) ?
2) Java doesn't use pointers then how linked list are implemented in Java ?
I don't see how it would be possible.
Java does have pointers. They're just called references in Java, but they're basically the same thing. Every variable pointing to an object is a reference, or pointer, to the object. If the variable is null, and you try to dereference it, you get a NullPointerException.
If you can live with some silly limitations, such as having a fixed maximum length for the list and allocating all of the potential elements up front, you can use indexes to replace pointers.
This can make the elements themselves smaller, since if you know a good boundary on the number of elements (which you have to, for the pre-allocation to work) you can adjust the size of the index, but you can't do that with pointers. For a list with at most 1,000 elements, you might get away with a uint16_t index, which is 1/4 the size of a pointer on a 64-bit architecture.
On the other hand, indexing involves address calculations which are not needed when just following direct pointers, so there might be a performance cost.
As for 1, I don't think that's possible.
For 2, you should check out this excellent resource http://cslibrary.stanford.edu/
for java - it's references which are being used by LinkedList
http://docs.oracle.com/javase/6/docs/api/java/util/LinkedList.html
1 - No. The point of a linked list is that it is dynamic data structure. This means that you can change its size at run time (vs having to know what size it is when you compile the program). This can only be done with pointers, because when you allocate some new memory you need to know how to find it.
And you could do it without structs, but they are the most suitable structure.
2 - Java has references to objects. They are basically the same as pointers, except you can't do arithmetic with them, and they are type safe.
1 - Absolutely. Use a set of parallel arrays (one for each attribute) and use the array indices as your pointers. Generations of FORTRAN programmers (and college students like myself who learned from those FORTRAN programmers) used this approach for all sorts of data structures - lists, trees, stacks, queues, etc. It's ugly, it's a huge pain in the ass, it has some real limitations, but it's certainly possible. Pointer types and aggregate types make implementation of data structures easier, but they're hardly required.
2 - Java uses pointers all over the place; it just doesn't expose operations on pointer types to the programmer. Any time you use a reference type (basically, anything that requires you to use new to create an instance) you're working with a pointer.
1) Since all memory allocation somehow involves pointers, and you need to allocate additional memory for new entries in the list, a traditional linked list that grows and shrinks with the number of elements is not possible.
2) Java has references, which are the same as pointers, you just can't do pointer arithmetic (like int* p = q + 1;) on them.
A linked list in C without pointers or structs? Well... Maybe. You can have a set of arrays, one would contain the data, the other would contain the index of the next node. Of course, arrays use pointers.
Java uses reference which are almost, but not quite, pointers.
1) The answer that suggests "silly limitations" is probably your best bet if you absolutely have to, although some of thos limitations compelete defeat the point of using a linked list. For instance easily resizable goes to impossible to resize. Why would you want to not use pointers?
2) Just because you don't see them doesn't mean they arent there. A more accurate statement would be "I don't have to deal with the pointers or their arithmatic in Java." If you need to prove to yourself that pointers are under the covers do the folowing process with both int and Integer
0) (we're good code heads)declare and initialize variable to 3
1) print it
2) pass it to another function
3) increment it in that function
4) print it again
5) return
6) print from calling function.
With an int type you will print 3 4 3, with an Integer you will print 3, 4, 4. This is because objects are passed by reference meaning you are still dealing with pointers under the hood. References are different because (for the most part) you don't have to deal with them.
In java is it possible and if not how to calculate in c?
if it's really array (not a pointer), you can do sizeof(arr)/sizeof(*arr)
In Java, the length of a primitive array is array.length, while the length of an ArrayList (and most other collections) is arrayList.size()
In C, the length of an array is sizeof(array) / sizeof(array[0]), but this is nearly useless since you can't pass arrays as arguments (they degenerate to pointers). The normal way to find the size of an array in C is to pass it as an extra argument to the function, or sometimes to terminate it with a sentinel value (eg. strings are \0 terminated)
There is no way to calculate that. in C (not C++, which has std::array and std::vector) an array is transmitted as its pointer, which you might increase by some offset. So you really don't know the runtime size of an "array", except by some conventions.
In particular for formal arrays, there is no way to know the size of the actual array passed
e.g. as void f(int arr[]) { /*...*/ } unless you give a static dimension.
Likewise, with an external array declared as extern int xarr[]; you cannot get its dimension with sizeof(xarr)/sizeof(xarr[0]).
In C, there is no way of calculating the size of array if you have only a pointer to it. You must store it in separate variable.
In fact you HAVE TO keep the size of an array in separate variable because you have to allocate memory if you want to use dynamic-size array.
And if you want to use fixed-size array you know it's size by the time you're writing your code so why not use #define, variable or const to store it?
Java is totally different language than C and the philosophy of programming is different-you should always keep that in mind.
In Java, you should use array.length, look here for example: http://www.roseindia.net/help/java/a/java-array-length.shtml
Simply, there is no possibility if you recieve only a pointer. That's why main has an argc argument. It defines the number of entries in argv. If you have an array "datatype" (actually the same as a pointer, but the behaviour depends on the context), you can use
int[] arr = new int[10];
sizeof(arr)/sizeof(int) // or whatever type is contained in ``arr``
What is the reason why Wrapper classes (like Integer, Double, etc.) don't have a setter for their inner primitive value ?
I am asking this because that kind of functionality would have simplified calculus, and have made the Java language a little more flexible .
Let me give you some examples.
1) Let's take the following example:
Integer x = new Integer(5);
x++;
The previous code behind the scenes is performing autoboxing . Something like:
int x_tmp = x.intValue();
x_tmp++;
x = new Integer(x_tmp); // Yes that's a new memory allocation
Because of this problem doing calculus on Wrapper is slower than performing on plain primitive types. With a setter it would've been more easy to increment the inner value, without allocating another object on the heap.
2) Another issue that is bugging me is that is impossible in Java to write a swap function like I can do in C (using pointers) or in C++ (pointers or references).
If i write void swap(Integer x, Integer y) I cannot acces the inner value because, and It is going to be impossible for me to swap the values.
PS:
A friend of mine suggested that i should consider the bigger picture, and think in terms of concurrency and type immutability.
So do you have an explanation for this ?
Thanks!
Wrapper classes are usually not used unless you need to put them into a collection. If they were mutable it would make problems if used inside sets and as keys for hashtables.
Sets and hashtables need the hash value to be always the same.
1) With a setter, the wrapper types would be mutable. Immutability is a good thing in many ways... threading, general understandability of the code etc. Personally I think it's a shame that Calendar and Date are mutable, for example.
In fact, your expansion of x++; isn't quite right - it uses Integer.valueOf which doesn't always create a new value. For example:
Integer x = 5;
x++;
Integer y = 5;
y++;
// This prints true
System.out.println(x == y); // Compare references
Only a limited range of Integer values are cached like this (the spec defines what values must behave this way, but allows for a wider range if the JRE wishes to do so)... but it does mean that it won't always be creating a new object.
2) Yes, Java doesn't have pass by reference. Frankly I very rarely find that to be a problem. How often do you really need to swap the values of variables?
Caching Integers in the range from -128 to 127 requires immutable Integers. Consider the follwoing code:
Integer id = Integer.valueOf(1); // a new Integer, cached in Integer class
// and somewhere else
Integer key = Integer.valueOf(1); // returns the cached value
Now if Integer was mutable and had a setter and someone did
key.setValue(2); // not legal Java code, just for demonstration
this would change the value of id too and, to a lot of peoples surprise:
Integer one = Integer.valueOf(1);
if (one != 1)
System.out.println("Surprise! I know, you expected `1`, but ...");
In Java, Strings and wrapper classes are designed as immutable to avoid accidental changes to the data. You can check the below article for further information.
Why Strings and Wrapper classes are immutable 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";