Java 使用包装类代替静态变量

Java 使用包装类代替静态变量,java,static,binary-tree,binary-search-tree,wrapper,Java,Static,Binary Tree,Binary Search Tree,Wrapper,这是我在StackOverFlow的第一个问题: 在《破解密码访谈》(第五版)一书的帮助下,我正在学习面试, 我正在解决下一个问题: 实现一个函数来检查二叉树是否是二叉搜索树(Q 4.5第86页) 在我们继续之前,我只想提醒您二叉搜索树与简单二叉树之间的区别: 二叉搜索树施加的条件是,对于所有节点,左侧子节点小于或等于当前节点,而当前节点小于所有右侧节点 因此,这本书提供的解决方案之一是以顺序遍历的方式扫描树,并动态检查我们访问的每个节点是否都大于上一个节点,并且假设树不能有重复的值: publ

这是我在StackOverFlow的第一个问题: 在《破解密码访谈》(第五版)一书的帮助下,我正在学习面试, 我正在解决下一个问题:

实现一个函数来检查二叉树是否是二叉搜索树(Q 4.5第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!
}

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

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

拥有包装器类的原因是因为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!
}
publicstaticbooleanchcheckbst(treenoden){
WrapInt计数器=新WrapInt();
返回checkBST(n,计数器);
}
公共静态布尔校验BST(TreeNode n,WrapInt计数器){
如果(n==null)返回true;
//检查/递归左
如果(!checkBST(n.left,counter))返回false;
//检查电流
如果(n.data在这里:

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!
}
publicstaticbooleanchcheckbst(treenoden){
WrapInt i=新WrapInt();
i、 值=整数。最小值;
多切克布斯特(n,i);
}
私有静态布尔值doCheckBST(TreeNode n,最后打印的包装){
如果(n==null)返回true;
//检查/递归左
如果(!checkBST(n.left,最后一次打印))返回false;
//检查电流

if(n.data如果有可能同时运行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  = ??
。。。


如果每个sort实例都有自己的最后一次打印,那么就不会有同步问题。

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

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!
类包装{
公共int值=Integer.MIN_值;
} 
公共静态布尔检查BST(TreeNode n,WrapInt lastPrinted){
如果(n==null)返回true;
//检查/递归左
如果(!checkBST(n.left,lastPrinted))返回false;
//检查电流

if(n.data我认为这是一种更正式的方法,可以避免公共静态上下文属性(例如线程安全性),这不是对象编程中的最佳方法。但是有标准的原始包装类,如:
它可以用来代替新类。通常包装模式比您的示例更通用:

感谢您的快速回答。因此,基本上要使用包装,我需要创建它的实例并将其作为函数参数之一传递?是的,因为这允许checkBST保持为无状态静态方法。然后它允许您需要从多线程使用该方法,因为没有全局状态。
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!