BST intersection, NullPointerException

2019-09-17 04:24发布

问题:

I am trying to create a new BST from the intersection of 2 known BSTs. I am getting a NullPointerException in the intersect2 method int he second case, at the line "cur3.item.set_account_id(cur1.item.get_accountid()+ cur2.item.get_accountid());". I know you get the error when you try to dereference the variable without initializing it but i think i am initializing it? I'm not really sure. I would appreciate the help.

public static Bst<Customer> intersect(Bst<Customer> a, Bst<Customer> b){
     return( intersect2(a.root, b.root));
 }

  public static Bst<Customer> intersect2(BTNode<Customer> cur1, BTNode<Customer> cur2){
  Bst<Customer> result = new Bst<Customer>();

// 1. both empty -> true
  if (cur1==null && cur2==null){
  result=null;
 }
// 2. both non-empty -> compare them
 else if (cur1!=null && cur2!=null) {
  BTNode<Customer> cur3 = new BTNode<Customer>();
  cur3.item.set_account_id(cur1.item.get_accountid()+ cur2.item.get_accountid());
  result.insert(cur3.item);
  intersect2(cur1.left, cur2.left);
  intersect2(cur1.right, cur2.right);
 }

// 3. one empty, one not -> false
else if (cur1==null ||cur2==null){
  BTNode<Customer> cur3 = new BTNode<Customer>();
  cur3.item=null;
  intersect2(cur1.left, cur2.left);
  intersect2(cur1.right, cur2.right);
}
 return result;
}

Here is the image of the problem:

回答1:

A NullPointerException can be caused by a number of things. In your given example, cur1 and cur2 are not null, but there is no guarantee that cur1.item, cur1.item.accountId (and similarly for cur2) are not null.

Being as you have no description for the underlying implementation, I cannot assist further. I can suggest that you do some of a few things:
1.) check the implementation of your objects (if this happens EVERY time, there may be some sort of initialization problem.
2.) Whenever you create an instance of your item, do you make sure to specify the accountId field? Try giving a default value for this field so it cannot be null. (try some sort of illegal value [eg -1, false, etc] and test for it.

If you would post more implementation details, I (or someone) may be able to directly identify the problem.

Regards.

Edit:4/20@17:11 Here's an example of what you should be doing.

public class Customer {  
    private int accountId;  

    public Customer() {  
        this.accountId = 0;  
    }  

    public Customer(int account_identification) {  
        this.accountId = account_identification);  
    }  

    //As a side note, general practice implies fields be private  
    //Use a method (hence the term 'getter' and the reciprocal, 'setter')  
    public int getId() {  
        return this.accountId;  
    }  

    public void setId(int replacement_account_identification) {  
        this.accountId = replacement_account_identification;  
    }
}


回答2:

It is because the item variable in Customer object is not initialized.



回答3:

Does creating a BTNode automatically allocate its member item ?

You do:

cur3.item.set_account_id(.. )

For this to succeed, both cur3 and cur3.item need to be not null.

Same applies to cur1 and cur2 as well, that you reference later in that line.

And the example of the 3rd case shows that BTNode.item can be null in some scenarios:

cur3.item=null;