【问题标题】:Using wrapper class instead of static variables使用包装类而不是静态变量
【发布时间】:2015-04-21 11:21:16
【问题描述】:

这是我在 StackOverFlow 上的第一个问题: 我正在借助《破解密码面试》(第 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;
}     

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

【问题讨论】:

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


    【解决方案1】:

    这是一种您可以创建 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!
    }
    

    【讨论】:

    • 感谢您的快速回答。所以基本上要使用包装器,我需要创建它的一个实例并将其作为函数参数之一传递?
    • 是的,因为这允许 checkBST 保持为无状态静态方法。然后它允许您在多个线程中使用该方法,因为没有全局状态。
    【解决方案2】:

    给你:

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

    【讨论】:

      【解决方案3】:

      如果有可能同时运行 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,则不会出现同步问题。

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          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!
          

          }

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-01-17
            • 1970-01-01
            • 2016-03-27
            • 2012-02-13
            • 2012-06-13
            • 2012-08-10
            • 2021-12-13
            • 1970-01-01
            相关资源
            最近更新 更多