【问题标题】:How to handle this class visibility issue?如何处理此类可见性问题?
【发布时间】:2015-01-03 07:10:35
【问题描述】:

我有一个 BinarySearchTree 实现,它实现了接口 Tree 的公共 insert 方法,如下所示。

public class BinarySearchTree<T extends Comparable<T>> implements Tree<T> {
public boolean insert(T value) {
Node<T> nodeInserted = insertValue(value); //call private method to insert. 
 return (nodeInserted != null);
}

 protected Node<T> insertValue(T value) {
   //insert the node and then return it.
 }

 public Node<T> search(T value) {
        //search and return node.
    }

   //Node class for BST
  public static class Node<T extends Comparable<T>> {
    // Fields and getters and setters.
   }
}

这个想法是其他派生类(例如 AVL)树将覆盖方法 insertValue 为: `

public class AVLTree<T extends Comparable<T>> extends BinarySearchTree<T> {
 @Override
    protected Node<T> insertValue(T id) {
       //specific code to insert node in AVL
    }

 // AVL Node
  public static class AVLNode<T extends Comparable<T>> extends Node<T> {
    // Fields and getters/ setters
  }
}

现在我有了另一个类 TreeMap,可以使用 RB 树或 AVL 树来实现。我正在尝试将 AVL 的代码重用为:

public class TreeMap<K extends Comparable<K>, V> implements Map<K,V> {
  private AVLTree<K> tree = null;

  @Override
  public V put(K key, V value) {
    //Here is the problem. 
  }
}

问题是:我想在 AVL 树中插入 key 属性作为节点,然后需要获取插入的节点并做一些处理工作。我既无法覆盖也无法获取 AVLTree 类的 insertValue()。

调用插入方法并获得布尔结果的一个选项。检查是否为真然后再次调用搜索方法获取节点然后进行处理。对于这个问题还有其他更好的解决方案吗?

我还需要一个建议。我已将 Node 类声明为静态类,仅与 BST 相关。我需要另一个用于 AVL 的节点类,并考虑扩展静态类 Node。为了使 Node 在另一个包中可见,我必须声明 public 以便它也可用于 AVLNode。它有任何设计问题吗?

【问题讨论】:

    标签: java performance tree binary-search-tree


    【解决方案1】:

    如果 insert 返回 null 而不是 false 并且找到的节点而不是 true 怎么办?然后,您将能够一次返回这两个信息。一个更好的主意是返回Optional&lt;T&gt;

    对于第二个问题,我实际上发现从另一个类的静态内部类扩展 Node 很奇怪。你说Node 只关心BST,但如果你在AVL 中需要它,情况并非如此,所以你最好有两个单独的类或由BST.Node 和@987654331 两者扩展的单个接口/抽象类@。

    【讨论】:

    • Node 的一个对象应该与 BinarySearchTree 密切相关,这就是为什么它是静态嵌套类。 AVLTree 也需要节点类,它也是 Node,所以我发现它适合扩展 Node。如果 Node 受到保护,我无法在定义 AVLTree 的另一个包中看到它,因此必须将其公开。然后它扩展了静态嵌套类 Node。恕我直言,我相信我们在 Java 中没有静态内部类。不是吗?
    • 这样使用,我不知道,但除此之外它是一个很常见的东西:Map.Entry(公共接口)、HashMap.Node(用作实现细节的私有类)、Rectangle2D。 Double 和 Rectangle2D.Float (公共,用于为双精度和浮点精度提供相同的功能)......在你的情况下令我不安的是,它似乎是一个实现细节,所以我不希望它公开跨度>
    • 我想像私有静态类一样使用 Node,只作为 HashMap 中的 Node 类。现在 AVLNode 也是 Node 所以我想扩展 Node 类,但是如果它是私有的(或受保护的),它将不适用于其他包中的派生类 AVLTree。所以即使我也想不出任何其他巧妙的解决方案。
    • insert() 方法不能返回 null 而不是 false,因为此方法是接口 Tree 的一部分,并且签名将返回类型指定为布尔值。所以不能改变。
    • @akhil_mittal 是的,但你不能改变你的界面吗?我正是这个意思。如果你使用的是Java 8,你甚至可以返回一个Optional&lt;T&gt;,否则你可以自己实现这个简单的类,或者使用这个实现grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/…,去掉里面不需要的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多