Using a wrapper class instead of static variables

This is my first question at StackOverFlow: I study the interview using the book “Cracking the code interview” (5th edition) and I solved the following problem:

Implement a function to check if the binary tree is a binary search tree (Q 4.5 p. 86).

Before moving on, I would just remind you of the difference between a binary search tree and a simple binary tree:

The binary search tree imposes the condition that for all nodes the left children are less than or equal to the current node, which is less than all regular nodes.

So, one of the solutions that the book offers is to scan the tree using an In-Order and on-the-fly traversal to check if each node we visit is larger and the last one, and assumes that the tree cannot have duplicate values:

public static int last_printed = Integer.MIN_VALUE; public static boolean checkBST(TreeNode n) { if(n == null) return true; // Check / recurse left if (!checkBST(n.left)) return false; // Check current if (n.data <= last_printed) return false; last_printed = n.data; // Check / recurse right if (!checkBST(n.right)) return false; return true; // All good! } 

Now, everything is fine here, but then the book quotes:

If you don't like static variables, you can configure this code to use a wrapper class for an integer, as shown below:

 Class WrapInt { public int value; } 

After reading the wrapper class in all of this and on other sites, I just couldn’t conclude why and how should I use a wrapper class here instead of a static variable?

+5
source share
5 answers

This is the mechanism by which you can instantiate WrapInt and pass it. Then you expose the value only to the code that needs to know about it, and not the public static non-final variable, which can be accessed and changed from anywhere.

The reason you have a wrapper class is because Java primitives are pass-by-value; going around int and then updating will not propagate the changes through the rest of your system.

It will look like this:

 public static boolean checkBST(TreeNode n) { WrapInt counter = new WrapInt(); return checkBST(n, counter); } public static boolean checkBST(TreeNode n, WrapInt counter) { if(n == null) return true; // Check / recurse left if (!checkBST(n.left, counter)) return false; // Check current if (n.data <= counter.value) return false; counter.value = n.data; // Check / recurse right if (!checkBST(n.right, counter)) return false; return true; // All good! } 
+2
source

Here you go:

 public static boolean checkBST(TreeNode n) { WrapInt i = new WrapInt(); i.value = INTEGER.MIN_VALUE; doCheckBST(n, i); } private static boolean doCheckBST(TreeNode n, WrapInt last_printed) { if(n == null) return true; // Check / recurse left if (!checkBST(n.left, last_printed)) return false; // Check current if (n.data <= last_printed.value) return false; last_printed.value = n.data; // Check / recurse right if (!checkBST(n.right, last_printed)) return false; return true; // All good! } 
+1
source

If there is a possibility that 2+ will be launched simultaneously. Static will be used for both sorts. Both sorts have access to the same static value.

 //thread 1 Sorting A = new Sorting(5,9,8); A.sort(); //thread 2 Sorting B = new Sorting(999,100,7); B.sort(); 

We cannot predict what / how the stream is processed.

So it may end in

 A.checkBST(5) // last_printed = 5 B.checkBST(999) // last_printed = ?? B.checkBST(100) // last_printed = ?? A.checkBST(9) // last_printed = ?? 

... ...

If each instance of the sort has its own last_printed, you will not have synchronization problems.

+1
source

I think this is a more formal way of avoiding a public static context property (for example, to ensure thread safety), which is not an optimal approach to programming objects. But there are standard classes of primitive shells: https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html that can be used instead of new classes. Typically, a Wrapper pattern might be more general than your example: What is a wrapper class?

+1
source

The problem with the static variable is that another class / method or something can change it and it will break your code. Can you do it like this:

 Class WrapInt { public int value=Integer.MIN_VALUE; } public static boolean checkBST(TreeNode n,WrapInt lastPrinted) { if(n == null) return true; // Check / recurse left if (!checkBST(n.left,lastPrinted)) return false; // Check current if (n.data <= lastPrinted.value) return false; lastPrinted.value = n.data; // Check / recurse right if (!checkBST(n.right,lastPrinted)) return false; return true; // All good! 

}

0
source

All Articles