How to make this Binary serach tree insert method work - java

I am implementing different methods in a binary search tree and am stuck on the insert method as it just doesn't seem to work.
I have been trying to implement the insert method for a while now but nothing seems to work it's always returning null. This method takes a user and adds it to the database. Using the User class.
public boolean beFriend(User friend) throws IllegalArgumentException {
User node = friend;
if (friend == null) {
throw new IllegalArgumentException();
}
if(root == friend) {
return false;
} else if(root.getKey() < friend.getKey()) {
if(root.getLeft() != null) {
root.setLeft(friend);
return true;
} else {
root.setLeft(node);
return true;
}
} else { if(root.getRight() != null) {
root.setRight(friend);
} else {
root.setRight(node);
return true;
}
}
return false;
}
I expect the User friend to be added to the database and output its details but the output that I am currently getting is null.

You don't define "root" in your method, therefore it's always null. You should define "root" to compare with friend and getting any data from it.

Related

How can I only refer to an object ONLY if it actually exists?

I am implementing a stack using linked list in java. The problem is that I get a nullPointerException when there is no element below, e.g. the StackNode.link does not exist. Therefore if I try assigning the StackNode.link I get the Exception.
Using an if statement to only run the code if it exists, I just get the Exception in the if statement. How do I go about this?
int pop() {
StackNode temp = top;
// update top
top = belowTop;
belowTop = top.link; // this is where I get the nullPointExcpetion
return temp.data;
}
I would expect that when top.link does not exist (e.g. is null) then belowTop would just be null. This would be fine, but as described I get the exception.
EDIT: This is what I tried with the if-statement
if (top.link != null) {
belowTop = top.link;
}
else {
belowTop = null;
}
You need to check if the variable top has been initialized or not:
...
if (top != null) {
belowTop = top.link;
} else {
// Handle the not initialized top variable
}
...
Probably a good solution is to throw a runtime exception if belowTop if not initialized, like
...
if (top == null) {
throw new IllegalStateException("Can't pop from an empty stack");
}
belowTop = top.link;
...
In this case you have to prepare also a method that gives the ability to check if the stack is not empty or not initialized. Here a complete proposal:
public boolean isEmpty() {
// Your logic here
}
// Better have a public access because it seems an utility library and
// it should be accessed from anywhere
public int pop() {
StackNode temp = top;
// update top
top = belowTop;
if (top == null) {
throw new IllegalStateException("Can't pop from an empty stack");
}
belowTop = top.link; // Now it works
return temp.data;
}
And you can use it as follow:
if (!myStack.isEmpty()) {
int value = myStack.pop();
// Do something
}
Give this one a shot:
if (top.link != null) {
belowTop = top.link;
} else {
//handle the exception
}
The above checks if the top.link is null, which is a valid check and won't cause a nullPointerException.

Java - how to return to a parent method?

I'm working on a method which should check in a guest to a room if the password matches. The method should also return that room.
public Room checkIn(String password, String guestName) {
assert (guestName != null);
if (this.password.testWord(password) && roomList.stream().allMatch(r -> r.getGuest().getName() != guestName)) {
roomList.forEach(r -> {
if (r.getGuest() == null) {
new Guest(guestName).checkin(r);
return r;
}
});
}
return null;
}
Eclipse gives me an error about returning within the forEach() method, since forEach() shouldn't return anything. I'm trying to have the checkIn() method return the room. Is there any way I can do this?
Use Stream.findFirst() to get the first matching element:
Optional<Room> r = roomList.stream().filter(r -> r.getGuest() == null).findFirst();
if (r.isPresent()) {
new Guest(guestName).checkin(r.get());
return r.get();
}

Checking to see if a binary search tree is degenerate

I want to check if a binary search tree is degenerate or not (Is it a linked list or indeed a tree?) I've been trying for a while and have come up with nothing that works. I did come up with a nonrecursive solution which I thought was quite clever but the specifications state it has to be a recursive solution and I'm having translating it from non-recursive to recursive.
Here's my non-recursive solution (well not really because size and height are both implemented recursively. This method however is not).
public boolean isDegenerate(){
if(this.size() == this.getHeight()){
return true;
}
return false;
}
Well, if you want a "more recursive" solution, how about this?
public boolean isDegenerate() {
if (this.left != null) {
if (this.right != null) {
return false; // not degenerate, has two children
} else {
return this.left.isDegenerate();
}
} else {
if (this.right != null) {
return this.right.isDegenerate();
} else {
return true; // we arrived at the bottom without seeing any node with two children
}
}
}

Loss of information during a for loop

I have a problem with this method:
private boolean reflectionEqualsSet(Object left, Object right) {
Set leftSet = (Set) left;
Set rightSet = (Set) right;
if (leftSet == null) {
// POF tricks: if set to serialize is null, the deserialized set is empty
return rightSet != null && rightSet.size() == 0;
}
// check size
if (leftSet.size() != leftSet.size()) {
return false;
}
// check values
for (Object currLeft : leftSet) {
boolean found = false;
for (Object currRight : rightSet) {
if (isEqual(currLeft, currRight)) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
The problem is:
I have an object with three random filled values in leftSet (2 UUID's and 1 Integer).
The values I have in my leftSet change completely in the for loop. While debugging I've found out that in the first iteration currSet already has completely different values and I can't figure out why.
In the inner loop with currRight this doesn't happen.
I've been debugging for hours and I've found the problem is in that line does anyone have an idea of why the values change? (Not the order, the values).
I know this isn't much information about the problem but that's all I can tell, I don't know how to explain it any better, sorry.
Thanks
First, your size check is off
// check size
// if (leftSet.size() != leftSet.size()) {
if (leftSet.size() != rightSet.size()) {
return false;
}
Next, I don't trust your isEqual method - please Override Object.equals(Object),
// if (isEqual(currLeft, currRight)) {
if (currLeft.equals(currRight)) {
return true; // <-- and just short-circuit with return true!
}
Obviously return false; after your for loop, and you can eliminate found.

i have a arraylist where i am verifying particular object is existing or not but even it exists it always returns false

hi i have class called userdata which returns the Userarraylist which is of type User. when ever i try to use contains method to check particular property is existing or not it always returns false why?
Actually i want the array list to be generic which should return the objects that are set in array list.
String className = data.getUserData().get(0).getClass().getSimpleName();
if(className.equalsIgnoreCase("User")) {
ArrayList<User> userdata=new ArrayList();
userdata = data.getUserData();
System.out.println(data.getUserData().contains(u.getUserId()));
if(userdata.contains(u.getUserName())) {
System.out.println(userdata.get(0).getEmailId());
}
}
The ArrayList is of Users while you are checking to see if it contains an ID or String.
userdata.contains(u);
The problem is, the ArrayList contains Objects, not the id's of those objects.
You are trying to compare the u.getUserId to the objects within the list, this is not a valid comparison (User != int)
UPDATE
boolean contains = false;
for (User user : userdata) {
// assuming userID is a number!!
if(user.getUserId() == u.getUserId()) {
contains = true;
break;
}
}
Just a side note, you should use either the instanceof operator or Class.equals method, instead of getting the simple name name checking for equality with some string.
You can't use contains in the list with User objects with its attributes i.e. user.userId or user.email.
Better to override equals method in User class which compare the attributes as below:
#Override
public boolean equals(Object obj) {
User other = (User) obj;
if (userId == null) {
if (other.userId != null)
return false;
} else if (!userId.equals(other.userId))
return false;
if (userName == null) {
if (other.userName != null)
return false;
} else if (!userName.equals(other.userName))
return false;
return true;
}
and then use contains as
userdata.contains(u)
It should be like
userdata.get(SOME_INDEX).getUserName.equals(u.getUserName());
or if you want to scan the whole ArrayList use this line inside a for loop
for (User user : userdata) {
if(user.getUserName().equals(u.getUserName())) {
return true;
}
}
Note that I have assumed there is a getter for the username attribute

Categories