使用包装类而不是静态变量

时间:2015-04-21 11:21:17

标签: java static binary-tree binary-search-tree wrapper

这是我在StackOverFlow上的第一个问题: 我正在学习采访" Cracking the code interview" (第5版)书, 我正在解决下一个问题:

  

实现一个函数来检查二叉树是否是二叉搜索树(Q 4.5 pg 86)。

在继续之前,我想提醒一下二进制搜索树与简单二叉树之间的区别:

  

二进制搜索树强加的条件是,对于所有节点,左子节点小于或等于当前节点,该节点小于所有右节点。

因此,本书提供的一个解决方案是使用按顺序遍历扫描树,并在运行中检查我们访问的每个节点是否大于最后一个节点,并假设树不能重复值:

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!
}

现在,在这里一切都很好,但随后这本书引用了:

  

如果您不喜欢使用静态变量,那么您可以调整此代码以使用整数的包装类,如下所示:

Class WrapInt {
    public int value;
}     

在这里和其他网站上阅读包装类之后,我无法得出结论,为什么以及如何在这里使用包装类而不是静态变量?

5 个答案:

答案 0 :(得分:2)

这是一种可以创建WrapInt实例并传递它的机制。然后,您只将值公开给应该知道它的代码,而不是可以从任何地方访问和更改的公共静态非final变量。

你拥有包装类的原因是因为Java原语是按值传递的;传递一个int然后更新它不会通过系统的其余部分传播更改。

这看起来像这样:

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!
}

答案 1 :(得分:1)

你走了:

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!
}

答案 2 :(得分:1)

如果有可能同时运行2+种类。静态将用于两种排序。两种排序都可以访问相同的静态值。

//thread 1
Sorting A = new Sorting(5,9,8);
A.sort();

//thread 2
Sorting B = new Sorting(999,100,7);
B.sort();

我们无法预测线程的处理方式。

所以这最终可能会出现在

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

... ...

如果每个排序实例都有自己的last_printed,则不会出现同步问题。

答案 3 :(得分:1)

我认为这是更正式的方法,如何避免公共静态上下文属性(例如线程安全),这不是对象编程中的最佳方法。但是有标准的Primitive包装类:https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html 可以用来代替新类。通常,Wrapper模式可以比您的示例更通用:What is a wrapper class?

答案 4 :(得分:0)

静态变量的问题是另一个类/方法或其他东西可以修改它,它会破坏你的代码。 你能做到这样吗:

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!

}