In this Trie implementation, children array elements are assigned null value individually using a for loop.
TrieNode(){
isEndOfWord = false;
for (int i = 0; i < ALPHABET_SIZE; i++)
children[i] = null;
}
However, by default, when we create an array of reference types in Java, all entries will have default value as null which is:
TrieNode[] children = new TrieNode[ALPHABET_SIZE];
The above step assigns default values of children array entries as null.
Is it required to have null assignment once again in the for loop inside that TrieNode constructor?
No it's not required - for each class variable, instance variable, or array component Java will always assign reasonable default value (like 0 for int or null for Object) - you can read more here
However notice that for local variables it's not guaranteed
The compiler will assign a reasonable default value for fields of the above types; for local variables, a default value is never assigned.
and that's why you are forced to initialize it manually
public void f() {
String s;
System.out.println(s); // will cause Error: java: variable s might not have been initialized
}
Related
I'm under the impression that the variable in for-each loop would get the value copied from the elements from the array. E.g.:
String[] strs = new String[] {"a", "b"};
for (String s : strs) {
s = "c";
}
for (String s : strs) {
System.out.println(s);
}
The above code has nothing to do with the original array strs and thus the output is still:
a
b
This is expected as the variable s in the for-each loop is actually a copy of the element. However, if I define my own class along with assignment constructor, the behavior changes:
class Node {
public Node(Integer value, String str) {
value_ = new Integer(value.intValue());
str_ = new String(str.toCharArray());
}
public Node(Node node) {
this(node.value(), node.str());
}
public Integer value() { return value_; }
public String str() { return str_; }
public Integer value_ = 0;
public String str_ = "null";
}
Node[] my_list = new Node[] {new Node(1, "a"), new Node(2, "b")};
for (Node n : my_list) {
n.value_ = 3;
n.str_ = "c";
}
for (Node n : my_list) {
System.out.println(n.value() + " " + n.str());
}
The output now is:
3 c
3 c
which means the variable n in the for-each loop is not a copy of the element but a reference.
Anyone can help explains why the behavior of for-each loop on String and my own class Node is inconsistent?
Thanks!
The value of the variable in the for-each loop is a copy of the values you are iterating on.
Remember that Java has two types of values: primitive values and reference values. Reference values are pointers to objects.
In the first example, s = "c" makes the variable s point to a new object. Since s is a local variable within the loop, there is no effect you can observe from the outside.
In the second example, n.value_ = 3 first finds the object that n points to: remember that n is a reference value, it's a pointer to an object. Then it goes and changes the value of field value_ within that object. These objects exist outside of the loop, so this change can be seen from the outside.
See also the very similar discussion on how the reference vs value semantics affect values passed to methods at Is Java "pass-by-reference" or "pass-by-value"?
In the first example, as you rightly pointed out, you are iterating through the str array and then setting the value to c. You are however not setting the value 3 to the str array. You can set the value to c by making the below changes to your first example.
`for (int i = 0;i<strs.length;i++) {
strs[i] = "c";
}`
This in effect is changing the value of the str array.
However in the second example you are making changes to the variables of the object passed in the for loop. Therefore the variables inside the object changed (in effect, you set the value to the objects variable)
I have an array with type Object. Then I assign it's values to null. But later I want to assign int values on null cells. Is that possible?
In these lines:
Queue[y]=new Int;
Queue[y]=num;
I am trying create an object Int type, in the null cell. But I get this error:
error: '(' or '[' expected
Queue[y]=new Int;
private Object Queue[];
public PriorityQueue(int capacity){
this.capacity=capacity;
Queue= new Object [capacity];
for(int i=0;i<=Queue.length;i++) {
Queue[i]=null;
}
}
public boolean insert(int num){
if (y<capacity){
Queue[y]=new Int;
Queue[y]=num;
y++;
return true;
}
else{
y++;
return false;
}
}
(I don't know what class you mean by Int - perhaps you mean java.lang.Integer, but perhaps you mean some custom class. It's not totally relevant to the answer, however)
You always need a parameter list when you invoke a constructor, even if it is empty:
new Int()
Or, if you mean to create an array, you need to specify the number of elements:
new Int[10]
However, you don't need the first assignment:
Queue[y]=new Int();
Queue[y]=num;
The second line overwrites the value in the first line, so it's actually just creating an object and then immediately discarding it.
You could simply write:
Queue[y]=num;
Note that this isn't actually assigning an int to an Object array element: due to autoboxing, the compiler automatically converts this to:
Queue[y]=Integer.valueOf(num);
so an instance of Integer is being added to the array. However, this conversion isn't something that you need to do yourself.
public void setData(double[] d) {
if (d == null) {
data = new double[0];
} else {
data = new double[d.length];
for (int i = 0; i < d.length; i++)
data[i] = d[i];
}
}
this method in my code is used to set the data of an array. I am also required to write a method called reset() that changes a given array to have a null value. Also, we are practicing overloading in this lab. There are four versions of setData() (double, int, float, long). Since a double array is used internally by the Stat class to store the values, do I only have to make one reset() method of type double?(I think I only need one...) Finally, please give me some hints as to going about this reset business because everything I have tried has failed miserably and usually consists of statements such as
"setData(double[] null)" which return errors.
Everything in java is pass by value; even references are passed by value. So by passing an array through a method, you can change the contents of the array, but you cannot change what the array points to. Now, if you are inside a class and happen to pass an instance member that you already have access to by virtue of being in the class, you will be able to set the array to null.
If you always want to be able to change what an array points to, then simply have a function which returns an array (instead of being void), and assign that returned value to the array of interest.
Because java is pass by value, you can't reassign a variable passed as a parameter to a method, and expect to see that change reflected outside.
What you can do, is put the array in some sort of wrapper class like this:
class ArrayReference<T> {
T[] array; // T would be either Double, or Long, or Integer, or whatever
}
and then:
void setData(ArrayReference<Double> myReference) {
myReference.array = null;
}
I'm not sure if I understood your question, but is it that what you want?
public class Stat {
private double[] data;
public void reset() {
data = null;
}
public void setData(double[] d) {
data = (d == null) ? new double[0] : Arrays.copyOf(d, d.length);
}
}
I'm confused on whether I need to do array initialization...
For this code:
private int[][][] rPos = new int[SIZE][SIZE][2];
Can I start using the array right way, like the following line?
getLocationOnScreen(rPos[i][j]); // pass an array of two integers
And, for this code:
View[][] allViews = new View[SIZE][SIZE];
I then have to make another nested loop, and initialize every View by calling their constructors like so:
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
allViews[i][j] = new View(ctor1, ctor2);
}
}
My question is, why didn't I need to do this for an integer array? And also, what did my "new" keyword do, when I typed View[][] allViews = new View[SIZE][SIZE];?
why didn't I need to do this for an integer array?
Whenever you create an array, the array elements are assigned the default value for the component type of that array. For an int, the default value is 0, so for an int[], all the elements will be initialized to 0 by default.
With reference type, however, the default value is null. So, the issue with those arrays are that, you might get potential NullPointerException, when you try to access some property or method in those array elements. Basically, with array of reference, we mean that the array elements are nothing but references to the actual objects. Initially they don't point to any object.
So, to access any property or method, you have to initialize each array elements to some instance, so as to avoid the NPE.
what did my "new" keyword do, when I typed View[][] allViews = new View[SIZE][SIZE];?
It created an array of array, of type View. The dimension being SIZE x SIZE. But since View is not a primitive type, but a reference type. The values are by default null, as already explained.
getLocationOnScreen(rPos[i][j]); // pass an array of two integers
Of course you passed an array of 2 integers. The component type of rPos[i][j] is an int[]. The default value is null for that too. But in this case, it wouldn't be null, as you have given the dimension for all of your inner array too.
If you change your array declaration to:
private int[][][] rPos = new int[SIZE][SIZE][]; // Missing last dimension
then the value of rPos[i][j] will be null.
Basically I have a variable, zlort = one;
I want to concatenate the value of zlort into a variable (object reference) name.
Like
BankAccount Accountzlort = new BankAccount;
I want the zlort in Account.zlort to actually be the replaced with value of zlort (one--meaning I want the value to be Accountone), and not zlort itself.
Is it possible to do this?
Thanks!
No you can't, but you might put the instance in a map:
Map<String,BankAccount> map = new HashMap<String,BankAccount>();
map.put("Account" + zlort, new BankAccount());
If you mean dynamically choosing the name to assign a variable to, then no.
You could use a HashMap to achieve the same effect.
It is not possible to change the name of a variable at runtime. That would lead to extreme security and stability problems when dealing with any real-world application.
However, as the two answers here have mentioned, a HashMap might acheive what you are looking for. (See the javadoc!!)
A HashMap (or any other map, for that matter) maps a Key to a Value. The concept is similar to a variable, which is a name -> value mapping. The only difference is that variables are part of the actual program code, which is effectively unmodifiable after compiling. A Map is a data structure that can be modified by the running program. This allows you to freely add key-value pairings to it.
Note that in Java, type-safety is encouraged through the use of Generics. Basically this ensures that the key can only be of one type (e.g. String) and the value can be of only one type (BankAccount). A thorough coverage of Generics can be found here.
You would declare this as follows:
Map<String, BankAccount> accounts = new HashMap<String, BankAccount>();
And then to add a key-value pair to the map, you would use the put() method (which 'puts' a value into the map, associated with a key)
String key = "Key"
BankAccount value = new BankAccount();
accounts.put(key, value);
To retrieve it, you would use the get() method.
BankAccount retrievedValue;
retrievedValue = accounts.get(key);
After reading the explanations in your comments, the fact that you can't use an array but can use an `ArrayList'...
Rather than creating a new variable name (or array element, or map value) for each BankAccount, you can probably use scope to your advantage.
Scope is the concept that a reference to a variable only has meaning within a certain part of code. If you declare a variable inside a method, that variable can only be seen within that method. A variable declared within a block (a loop, if statement, etc ) can only be seen from within that block.
Class fields have a different kind of scoping that can be adjusted with keywords (see here).
For example:
public class ScopeExample
int classInt = 10;
public void method() {
int methodInt = 0; // This integer can only be seen by code in
// this method
}
public void method2() {
//doSomething(methodInt) // This line won't compile because i is
// declared in a different method!
doSomething(classInt); // This line will compile and work
// because x is declared in the class that
// contains this method.
int index = 0;
while (index < 3) {
int whileInt = index; // This integer can only be seen from within
// this while loop! It is created each
// loop iteration.
doSomething(whileInt);
}
doSomething(whileInt); //This line won't work, whileInt is out of scope!
}
public doSomething(int a) {
System.out.println(a);
}
}
SO! If you create a BankAccount object within the loop, you don't have to worry about creating a new name for the next one. Each time the loop iterates it will become a new object (when you create it).
If you have to store it, you definitely will need to use an array or other data structure (ArrayList!).
Building on the idea of scope, you -can- have the same variable name for each new BankAccount. A variable reference name isn't guaranteed to be paired with the object that it refers to. That is a convenience to the programmer, so you don't have to know the exact memory address it is being stored in.
For example:
public static void main(String[] args) {
Object o;
int i = 0;
while (i < 5) {
Object reference = new Object(); // Create a new Object and store
// it in 'reference'
o = obj; // The Object 'o' now refers to the object in 'reference'
i++;
}
System.out.println(o); // This should print information about the
// LAST object created.
}
The new Object created in the loop does not belong to 'obj'. You as a programmer use 'obj' to point to the Object. The program doesn't really know what obj means, other than the fact that it points to the Object you just created.
Finally, you can use this along with an ArrayList to make your life easier.
public static void main(String[] args) {
// Our new ArrayList to hold our objects!
ArrayList<Object> stuff = new ArrayList<Object>();
int i = 0;
while (i < 5) {
Object obj = new Object(); // Create an object and make obj point to it.
stuff.add(obj); // Put "the object that 'obj' points to" in 'stuff'.
i++;
}
// This loop goes through all of the Objects in the ArrayList and prints them
for (int index = 0; index < stuff.size(); index++) {
System.out.println(stuff.get(i)); // This will print a single
// object in the ArrayList each time.
}
}