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.
Related
I am using a linked list without using collections class for data structure practice.
I wanted to remove an element from the linked list after passing the element value to function
This is the function that i've written.
public boolean remove(String s)
{
if(head.getName().equalsIgnoreCase(s))
{
head = head.getNext();
return true;
}
else
{
Node p =head;
Node current=p.getNext();
while(true) {
if(current == null || current.getName().equals(s)) {
break;
}
p = current;
current = current.getNext();
}
if (current == null)
{
p.setNext(current.getNext());
return true;
}
}
return false;
}
i'm using Node p to store the previous node and current node.
The code falls in the return false section and there is no change in the list.Also i'm getting a null pointer exception warning in the p.setNext(current.getNext()) here.
Please let me know where i'm making mistake.
Regarding the Null Pointer Exception this should ring a bell
if (current == null)
{
p.setNext(current.getNext());
return true;
}
current is null and you are trying to invoke a method from it.
Also it doesn't seem you handle the corner cases like the list is empty or having one element.
current == null
is the not found case. When current == null we should return false, and calling current.getNext() will give the null pointer error. Similarly, the found case is not getting into the block you want. It should suffice, I think, to say if (current != null) where you have if (current == null)
I found https://www.geeksforgeeks.org/linked-list-set-3-deleting-node/ helpful.
Instead of checking true condition based on current value which possibly may or may not be null, you should be having one boolean flag.
This flag value can be made true if you find the passed element.
while(true) {
if(current == null || current.getName().equals(s)) {
flag = true;
break;
}
p = current;
current = current.getNext();
}
if (flag)
{
if(current!=null)
p.setNext(current.getNext());
return true;
}
The Inventory consists of two arrays, one an array of objects[10] and one an array of ints[10]. The array of objects is to identify an item, and the array of ints is supposed to keep track of how many you have. For some reason the code is producing all kinds of errors. Not really sure what to do!
public void additem(Object newItem) {
if (itemsInInventory == 0) {
invent[0] = newItem;
inventItemAmount[0]++;
itemsInInventory++;
}else if (itemsInInventory > 0) {
for (int i = 0; i < itemsInInventory; i++) {
if (invent[i].getItemNum() == newItem.getItemNum()) {
inventItemAmount[i]++;
} else {
invent[itemsInInventory] = newItem;
inventItemAmount[itemsInInventory]++;
itemsInInventory++;
}
}
}
}
Complete code can be found here: https://github.com/YungSheep/HitsujiStories
I see in your GitHub code that your inventory is limited to 10 ; and your if-else condition doesn't hold any case for itemsInInventory > 10, that will first give you an idea of where your NPE comes from. It might be better for you to change your current else if condition to something like "a > 0 && a <= max" then add a case when it's higher than your max capacity.
EDIT : Also, I'm pretty sure I know why you get messed up amounts for each type of item : if you imagine the if-else statement inside a loop, the item slot [0] would only be accessible once, when the player has an empty inventory. That means I can't add up any further in the slot [0] if I picked an item and set itemsInInventory to another number than 0 ! You might have to rebuild your if-else contents.
SECOND EDIT : In case you find it messy to code, I suggest you to make an InventorySlot class :
public class InventorySlot {
private Object object;
private int amount;
// CONSTRUCTOR (assuming you don't instanciate filled slots)
public InventorySlot() {
this.setObject(null);
this.setAmount(0);
}
// GETTERS AND SETTERS
public Object getObject() {
return this.object;
}
public int getAmount() {
return this.amount;
}
public void setObject(final Object object) {
this.object = object;
}
public void setAmount(final int amount) {
this.amount = amount;
}
// METHOD THAT ADDS NEW ITEM IF MATCHES. RETURNS BOOLEAN TO TELL IF SUCCEEDED
public bool addIfMatches(final Object object) {
if (this.getObject.getItemNum() == object.getItemNum()) {
this.setAmount(this.getAmount++);
return true;
} else {
return false;
}
}
// AND OTHER USEFUL METHODS...
}
Hope this helps you, happy coding !
I am currently trying to implement a binary search tree shape comparison and am having trouble with one line of my code.
if(treeStructOne.getHeight() == 1 && treeStructTwo.getHeight() == 1) //Base Case, if both are empty then they must be equal!
{
return true;
}
if(treeStructOne.getHeight() != treeStructTwo.getHeight()) //First make sure height is the same, if not, must be unequal
{
return false;
}
if(treeStructOne.hasLeft() && treeStructTwo.hasLeft())
{
return similar(treeStructOne.getLeft(),treeStructTwo.getLeft());
}
if(treeStructOne.hasRight() && treeStructTwo.hasRight()) //PROBLEM IS HERE
{
return similar(treeStructOne.getRight(),treeStructTwo.getRight());
}
return false;
The problem occurs when a node on Tree 1 and 2 has a left child, but only tree 1 has a right and not Tree 2. After it checks that they both have left children, it does not run the the check on right children if left is true. Is this to do with the way recursion works in java?
if both trees hasLeft() returns true then your method will return in that if clause. My guess is you want to assign the result from the similar call in the last two if clauses and after the if clause do something like
return leftSimilar && rightSimilar;
The first two if's will work, but the last part should capture the conditions of p implies q which is ~p or q for both left and right. In other words, if treeStructOne has a left subtree and treeStructTwo has a left subtree, then check to see if they are similar (return similar...)
if(treeStructOne.getHeight() == 1 && treeStructTwo.getHeight() == 1) //Base Case, if both are empty then they must be equal!
{
return true;
}
if(treeStructOne.getHeight() != treeStructTwo.getHeight()) //First make sure height is the same, if not, must be unequal
{
return false;
}
return (treeStructOne.hasLeft() && treeStructTwo.hasLeft()
? similar(treeStructOne.getLeft(),treeStructTwo.getLeft())
: false)
&& (treeStructOne.hasRight() && treeStructTwo.hasRight()
? similar(treeStructOne.getRight(),treeStructTwo.getRight())
: false);
The return statement immediately returns from the current method, i.e. the remainder of the method will not be executed.
In your case, you want to make two recursive calls before returning from the method. You can do this with:
boolean similarLeft;
if(treeStructOne.hasLeft() && treeStructTwo.hasLeft()) {
similarLeft = similar(treeStructOne.getLeft(),treeStructTwo.getLeft());
} else {
similarLeft = ?; // TODO what is good condition here?
}
then do the same for the right side and conclude with
return similarLeft && similarRight;
However, for truly ideomatic java, I'd do the null checks after invoking the method rather then before it, thereby reducing code duplication:
boolean similar(TreeStruct x, TreeStruct y) {
if (x == null) {
return y == null;
} else {
return y != null && similar(x.left, y.left) && similar(x.right, y.right);
}
}
EDIT: Solved. Returning a 0 works, apparently!
Ok so long story short, I have to return an int value, but nothing when a Linked List is empty. How do I do it?
public int countDuplicates() {
int duplicates = 0;
ListNode current = front;
int num = current.data;
current = current.next;
while(current != null) {
if(current.data == num) {
duplicates++;
} else {
num = current.data;
}
current = current.next;
}
return duplicates;
}
When I try this:
if(front == null) {
return ;
}
This doesn't work. What can I do?
You can rather throw an IllegalArgumentException: -
if(front == null) {
throw new IllegalArgumentException("List is empty");
}
If your method returns an int you must determine an acceptable value to represent "nothing". Such as 0 or if valid results are >= 0, use a negative value such as -1 to indicate "nothing".
Alternatively, modify your method to return an Integer object in which case you can return null.
It is possible for you to either define a fixed value, such as Integer.MIN_VALUE, that would indicate that the list is empty, or change the declaration of your method to public Integer countDuplicates(), and return null when the list is empty.
To keep the code as you have it now, you must either return an int, throw an exception, or exit.
Return an int: You'll have to specify a certain int value as the "fail" value and make sure that it is never the case that this value is hit during "normal" execution.
Throw an exception: Detailed in another answer - you've already shot it down.
Exit the program... if it makes sense to do that.
The best option may be to change the code - make the function return an Integer, for example, so the null option is there. There are surely other ways to work around it, as well.
you can change the return value from int to object like this
public Object countDuplicates() {
if(////condition)
return ///int;
else
return null;
You could return a negative value or change the return type to string and parse the result to int.
If you don't want to (or can't) throw an exception, return some "exceptional value", such as a negative number. For example, Java has a lot of indexOf(Object somethingToLookFor) methods that return a -1 if the item isn't found.
In your example, -1 works as exceptional because there can never be -1 duplicates.
Personally, I would just return 0 for an empty List. An empty list has 0 duplicates. But if the spec insists on something exceptional, return -1.
public boolean isEmpty(){
if (head == null) return true;
else return false ;
}
I get an error in the code from this part of my code:
public boolean findCustomer(String inPersonalNumber){
// check if personal number already exist
for (int i=0; i<customerList.size();i++) {
if(customerList.get(i).getCustomerPersonalNumber().equals(inPersonalNumber)){
return true;
}
}
return true;
}
When I remove the first return true and instead to the last return true, it don't get the error in my eclipse code, but why can't I have the first place and would this be the same? Thanks!
EDIT: The error message from eclipse say: This method must return a result of type boolean. I'm confused because isn't that what I have done?!
Yes, a break must be in the code
Can I write the method in some other way?
EDIT NUMBER 2
Why isn't this code working?
public boolean findCustomer(String inPersonalNumber){
// check if personal number already exist
for (int i=0; i<customerList.size();i++) {
if(customerList.get(i).getCustomerPersonalNumber().equals(inPersonalNumber)){
return true;
}
else {
return false;
}
}
}
This method returns a boolean value so I don't understand why I get an error!? The code looks right to me?
Your edit #2 doesn't compile because there is a possibility that your code won't enter the for-loop. This will be the case if customerList.size() is 0. To fix this, you'll simply need to add a return statement after the for-loop as well:
// check if personal number already exist
for (int i=0; i<customerList.size();i++) {
if(customerList.get(i).getCustomerPersonalNumber().equals(inPersonalNumber)){
return true;
}
else {
return false;
}
}
return false;
Another point here is that this code doesn't logically make much sense: it will only return true or false based on the first item in your list. And this is probably not what you want. So take a closer look at several of the other answer here, many of which are good examples for how you can do this.
public boolean findCustomer(String inPersonalNumber){
boolean result = false;
// check if personal number already exist
for (int i=0; i<customerList.size();i++) {
if(customerList.get(i).getCustomerPersonalNumber().equals(inPersonalNumber)){
result = true;
break;
}
}
return result ;
}
When I remove the first return true and instead to the last return
true, it don't get the error in my eclipse code, but why can't I have
the first place and would this be the same?
If you remove the second return statement the code would be able to run and not return a value - this is not possible as you defined the method to have a return type of Boolean. So it must always return a value no matter what.
Just change the second return statement to false, should do what you want.
Looks like you have turned off the Build Automatically feature of eclipse. It maybe complaining about an error that used to be present when you still hadn't typed in your code fully! This can also happen if you have back-dated your system for some reason.
Also, shouldn't you be returning false if the condition doesn't satisfy?
public boolean findCustomer(String inPersonalNumber) {
// check if personal number already exist
for (int i = 0; i < customerList.size(); i++) {
if (customerList.get(i).getCustomerPersonalNumber().equals(inPersonalNumber)) {
return true;
}
}
return false;
}
First return will return only in case of all conditions satisfied, but this method should be returning boolean as per code. It would be expecting a return in failure case also.
Removing first return won't affect compilation as it has a return in second place which will work without any condtions.
Edit : Answer for your second question
This code has two return's, but what if your customerList is size 0, in that case also, method must return boolean. right? for that only, compiler is asking.
BTW, code doesn't have null checks.
Your final code could be this. Keeping multiple return statements in code in not a good practice.
public boolean findCustomer(String inPersonalNumber) {
boolean retVal = false;
if (!(inPersonalNumber == null || inPersonalNumber.trim().equals("")
|| customerList == null || customerList.size() == 0)) { // inputs are valid to run this check
// check if personal number already exist
for (int i = 0; i < customerList.size(); i++) {
if (inPersonalNumber.equals(customerList.get(i).getCustomerPersonalNumber()) { // to avoid NPE, kept inPersonalNumber in check
retVal = true;
break;
}
}
}
return retVal;
}
Because your for loop looses meaning if you're returning true anyway.
If you want to stop loop use break; instead of first return.