Array Clone doesn't work - java

what is wrong with my code?
in the main method i am doing this:
int [] test=new int[48];
test=etable(Right[]).clone();
What i want is, that the 'test' array is exactly the same like the output of the 'etable' method.
my method called 'etable':
public static int [] etable(int [] right){
int [] blabla=new int[48];
...
return blabla[]
}
Thanks for your advise

what is wrong with my code?
This line is a compilation error:
test = etable(Right[]).clone();
If right (or Right) is a variable (declared with type int[]), then you should write the method call like this:
test = etable(right).clone();
If Right is a type, then that is not the correct syntax for creating an array. (And judging from how you have written the etable method, you should not be passing it a new array.)
The second problem is that this sequence doesn't make sense:
int test[] = new int[48];
test = etable(...).clone();
You are allocating an array of 48 elements ... and then throwing it away by assigning a different array reference to the test variable.
The third problem is that the clone() is most likely redundant anyway. Your etable method is allocating a new array (in blabla) and returning it. The calling code is then copying the new array. Unless the etable saves the reference to the blabla array somewhere, the copying step doesn't achieve anything.
The final problem is that if Right really is a variable name, then that is a serious Java style violation. In Java a variable name should NOT start with an upper-case letter.

Use for instance Arrays.copy():
int[] tmp = etable(whatever);
int[] test = Arrays.copy(tmp, 0, tmp.length);
As to your original code, this, for instance:
test = ebtable(Right[]).clone();
is not legal Java (what is Right anyway?).

Related

Calling get (array static method) from an array instance

New to Java, and OOP in general.
I'm doing an online Lynda course, and in the course there's an example of using Array.get to extract the 2nd item from an array:
String[] myFavoriteCandyBars = {"Twix", "Hershey's", "Crunch"};
System.out.println(Array.get(myFavoriteCandyBars, 2));
And the instructor explained that get is a static method from the "Array" class.
But when I tried defining:
`Array[] testarray = new Array[10];`
And using:
`testarray.get(testarray[10]);`
I get an error:
cannot resolve method 'get(java.lang.reflect.Array)'
But I don't understand why - the testarray is an object of class Array, and class Array has a method "get", so although it's bad practice, why can't I do it?
The Array class is an internal Java class containing only public static methods, and its intended use is to not be be directly instantiated. The following code:
testarray.get(testarray[10]);
fails because testarray is of type Array[], not Array, and therefore does not have the static method get() available. Hypothetically speaking, if you could call Array#get on an instance, it should work, but as mentioned above, Array cannot be instantiated.
A more typical way to use Array would be something like:
String[] testarray = new String[10];
testarray[1] = "Snickers";
System.out.println(Array.get(testarray, 1));
That is, create an array of the desired type, and then use Array#get to access whichever element you want.
get() is not a method in the array class, (as in a byte[] object). get() is in the Array class. Doing Array.get(testarray, 0) is what you want. Despite that, don't do this, do testarray[0] instead.
Whenever you use a static method, you shouldn't call it from an object, you should use the class instance, so instead of doing
Object o = new Object();
o.staticMethod();
Do:
Object.staticMethod();

Undesrstanding clone method for arrays

I've learnt that for arrays the clone method is well-behaved and we can use it. But I thought that the type of the elemetns the arrays hold should have implemented Cloneable interface. Let me provide some example:
public class test {
public static void main(String[] args){
Test[] arr_t = new Test[1];
arr_t[0] = new Test(10);
Test[] an_arr = arr_t.clone();
an_arr[0]= new Test(5);
System.out.println(an_arr[0].test); //5
System.out.println(arr_t[0].test); //10
}
public static class Test{
public int test;
public Test(int test) {
this.test = test;
}
}
}
DEMO
I thought that 5 should have been printed twice. The reason for that is by clonning arrays we're creating new arrays containing references to the objects the first array holded (Because the type of the elemnts does not implement Cloneable). Couldn't you straighten the things out?
It's not clear if it's neccesary the array element's type implements Cloneable.
It's a simple concept, but seems hard to explain. When you clone the array, you will have two district arrays in memory, but with the same values in their indexes.
In your second array an_arr doing an_array[0] = new Test(5) you will put another reference in the slot 0.
But the index 0 of the clone is in a different place from the cloned array.
Your example is valid if you do
Test[] arr_t = new Test[1];
arr_t[0] = new Test(10);
Test[] an_arr = arr_t.clone();
an_arr[0].test = 5; // look here, I changed the object
System.out.println(an_arr[0].test); //5
System.out.println(arr_t[0].test); //5
Now both will print the same value because they hold the same reference to the same object, but the place where this reference is stored, is different.
.clone() makes what's called a "shallow copy". That means it copies as little as possible when running the method; instead of copying the contents of the array, it just creates references to the contents of the original array.
If you change the references by calling:
new Test(5)
Then you've overwritten that reference, and get new data.
The alternative is a deep copy of the array. Those can be expensive to do on bigger objects, so they're not the default.
An array's clone() does the same thing regardless of type of array: it creates a new array of the same type and size and then it assigns (=) each element of array to each element of the new array. That's it.
So if you have a 3-element array pointed to by arr, and arr.clone() returns newArr, then after the creation of the new array it simply does this:
newArr[0] = arr[0];
newArr[1] = arr[1];
newArr[2] = arr[2];
That's it. The type of array is not relevant. There is no "cloning" or anything involved in the elements. It doesn't know (or care) if the element has some kind of method to clone (in fact, there is no general API for cloning in Java, anyway, so this would be impossible).
(And by the way, even if it somehow put cloned objects into the new array, the result in your example would still be the same, because you are assigning a new value into the array, so it doesn't matter what was there before.)
So your question is basically why:
Test[] arr_t = new Test[1];
arr_t[0] = new Test(10);
Test[] an_arr = new Test[1];
an_arr[0] = arr_t[0];
an_arr[0] = new Test(5);
System.out.println(an_arr[0].test); //5
System.out.println(arr_t[0].test); //10
and you can figure it out from there.
The "problem" here is that arrays hold references to object, not objects. Further, this has nothing to do with cloning.
When you execute:
an_arr[0] = new Test(5);
You are assigning the new object's reference to the first element.
Also, each array has its own references to Test objects. When you clone the array, only the references are copied (not the objects to which they refer).

Inexplicable Array assignment behavior in Java

So here it goes. I've been building a piece of software for a bigger project, and right now, I am simply baffled by the way Java treats my code. I have absolutely no idea as to why Java behaves the way it does right here.
It seems to skip part of my code, and assigns values to a different array than I expected when no according method is called.
I have walked over this for a few hours now with the IntelliJ Debugger, inspecting everything ever so closely, but I have not found a single reason as to why things happen the way they do.
package com.whatareyoudoing.java;
import java.util.Arrays;
/**
* WHAT THE ACTUAL DUCK
*/
public class WTF {
private int[] number;
private int[] oldNumber;
public WTF() {
number = new int[1];
oldNumber = new int[1];
}
public void putNumber(int c) {
number[0] = c;
}
public void putOld() {
if(Arrays.equals(oldNumber, number)) {
System.out.println("Nothing to do!");
return; //How on earth can they literally be the same?!
}
oldNumber = number;
}
public void doWTF() {
putNumber(1);
putOld(); // Works.
putNumber(2); // Expected Result: number = 2; oldNumber = 1 [NOPE] number = 2; oldNumber = 2
putOld(); // [NOPE] Simply Skips with "Nothing to do"
putNumber(3); // Same odd behaviour
putOld(); // Aaaand skips again.
}
}
After calling putNumber the first time, using putNumber again simultaneously puts the value in both variables (oldNumber and Number) instead of only in number[0].
I continued to simplify my code as far as possible so this example is more hands-on. Obviously, the real example where I found this had arrays longer than a single element.
I also tested it with multidimensional arrays, as well as object arrays. No change in the behavior.
I am completely puzzled now and have absolutely no idea how to go on. If you can shed any light on this topic, please do so. I am more than confused.
The following assignment statement:
oldNumber = number;
makes oldNumber and number point to the same underlying array. Perhaps what you want is to make a copy:
System.arraycopy(number, 0, oldNumber, 0, number.length);
See the documentation for System.arraycopy for full details.
This line isn't doing what you think it's doing.
oldNumber = number;
It isn't copying the contents of one array to another. It is making the reference variable oldNumber refer to the same array object as number refers to.
oldNumber ----> [1]
number -------^
So, any change through either variable writes through to the same array, and the change is visible through both references, which refer to the same array.
Then later you call Arrays.equals with references to the same array, so they are "equal".
You want to copy the number with this line instead:
oldNumber[0] = number[0];
When you assign
oldNumber = number
you don't make a copy of the values in the array. oldNumber will point to the exact same array (and future changes in either variable reflect in the other).
You can make a copy with
oldNumber = Arrays.copyOf(number, number.length);
In the putOld function you assigned the reference of the first array to the other. After the first call oldNumber is a pointer to number and if you change a value in one, the other one is affected too.
If you want to copy the values System.arraycopy().

how can i initialize my array when i cant initialize as null?

i have an array of strings which i want to convert to int, pretty simple and straightforward here is the code :
public static void main(String[] args) {
String myarray[]=readfile("[pathtothefile]");
int mynums[] = new int[myarray.length];
for (int i=0;i<myarray.length;i++){
mynums[i]=Integer.parseInt(myarray[i]);
}
System.out.print(Arrays.toString(mynums));
}
But the Problem here is, if i initialize "mynums" like this: mynums[]=null; i get NullPointerException on the following line:
"mynums[i]=Integer.parseInt(myarray[i]);"
what i have to do to solve it is
int mynums[] = new int[myarray.length];
here someone explained why it happens but i dont know how to initialize now! i mean sometimes i dont know how big my array can get and i just want to initialize it. is it even possible?
In Java everything is a pointer behind the scenes. So when you do mynums[]=null, you are pointing to a null. So what is null[i]? That is where your NPE comes from. Alternatively when you point it to an array, then you are actually accessing the i'th element of the array.
You have to first initialize the array because it allocates memory depending on the array size. When you want to add for example an integer to an array it writes the int into previously allocated memory.
The memory size won't grow bigger as you add more items.( Unless you use Lists or Hashmaps, ... but it's not true for generic arrays)
If you don't know how big your array will be, consider using SparseIntArray. which is like Lists and will grow bigger as you add items.
Briefly, in java an array is an object, thus you need to treat it like an object and initialize it prior to doing anything with it.
Here's an idea. When you're initializing something as null, you're simply declaring that it exists. For example ... if I told you that there is a dog, but I told you nothing about it ... I didn't tell you where it was, how tall it was, how old, male/female, etc ... I told you none of its properties or how to access it, and all I told you was that there IS a dog (whose name is Array, for sake of argument), then that would be all you know. There's a dog whose name is Array and that is it.
Typically, arrays are used when the size is already known and generally the data is meant to be immutable. For data that are meant to be changed, you should use things like ArrayList. These are intended to be changed at will; you can add/remove elements at a whim. For more information about ArrayList, read up on the links posted above.
Now, as for your code:
public static void main(String[] args) {
ArrayList<int> myInts = new ArrayList<int>();
// define a new null arraylist of integers.
// I'm going to assume that readfile() is a way for you get the file
// into myarray. I'm not quite sure why you would need the [], but I'll
// leave it.
String myarray[] = readfile("[pathtothefile]");
for (int i = 0; i < myarray.length; i++) {
//adds the value you've specifed as an integer to the arraylist.
myInts.add(Integer.parseInt(myarray[i]));
}
for (int i = 0; i < myInts.size(); i++) {
//print the integers
System.out.print(Integer.toString(myInts.get(i)));
}
}
What if you don't use an array but an ArrayList? It grows dynamically as you add elements.

Java; null pointer on newly created array with user-defined length

So, right after the public class declaration, I've declared an array as follows:
public String[] accept;
From here then, I'm looking to take user input to see how long this array should be - and following this, we'd enter into a loop to populate the array with Strings. I put the following into a method;
if (scanner.hasNextInt()) {
wcount = scanner.nextInt();
//create the array.
String accept[] = new String[wcount];
}
System.out.println(accept.length);
But unfortunately, no nice. Java returns with;
Exception in thread "main" java.lang.NullPointerException
Obviously, attempting to go straight into a for loop to populate the array, will also give the same results. At first glance, I'm assuming this has something to do with it being initialised as a public array outside of the method itself - but I'm honestly not too sure. Can anyone lend a hand on this?
You are declaring a new array in your if block, which is hiding your previously declared array. When the block exits, the variable goes out of scope and you get an NPE attempting to access the (unchanged) instance variable. Change your code to actually initialize your instance variable like so:
if (scanner.hasNextInt()) {
wcount = scanner.nextInt();
//create the array.
accept = new String[wcount];
}
System.out.println(accept.length);
You are recreating a new accept [] as local variable. Change your loop as below
if (scanner.hasNextInt()) {
wcount = scanner.nextInt();
//create the array.
accept = new String[wcount];
}
Change String accept[] to just accept within the if statement, you are redeclaring a new one within that scope, leaving the old one null.
String accept[] = new String[wcount];
declares a variable, and stores the reference to the new string array into it.
You probably want to use the previously declared variable instead. To do that, simply use assignment expression directly:
accept = new String[wcount];

Categories