Java: compare two object lists - java

I'm trying to compare two lists of same objects, those two lists are nodes_cc and nodes_volume. They contains several Node objects. A Node is defined by ID and VALUE. The nodes on the two lists can have common IDs but not common values.
I want to compare the lists like this: I control the first list list (nodes_cc) , if I meet a node that doesn't appear on the second list (nodes_volume), the control MUST stop, even if I will find other nodes that belong even to the second list. I was thinking to use a break so I tried this:
int count=0;
for (int i=0;i<cc_nodes.size();i++){
Node node = cc_nodes.get(i);
for(int j=0;j<volume_nodes.size();j++){
Node node2 = volume_nodes.get(j);
if (node.id==node2.id){
count++;
}
else {
break;
}
}
}
The problem is: the for cycle breaks only after the first check (count is 1), where i'm doing wrong? Can you help fix me this?

You could use some boolean, and check it after your inner for loop :
int count=0;
for (int i=0;i<cc_nodes.size();i++){
Node node = cc_nodes.get(i);
boolean found = false;
for(int j=0;j<volume_nodes.size();j++){
Node node2 = volume_nodes.get(j);
if (node.id==node2.id){
count++;
found = true;
}
}
if(!found)
break;
}

You can Override .equals() and .hashcode() method in Node object to use id as comparator and then :
int count=0;
for (Node node : cc_nodes){
if(volume_nodes.contains(node))
count++;
else
break;
}
You can add this in Node object (if id is int value)
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (id != other.id)
return false;
return true;
}

Related

ArrayList .contains() sometimes true, sometimes false

I´m writing a simple Program which simulates a graph. This is how i implement a vertex: ( i used the word nodes for neighbours, thats a little confusing maybe..)
public class Vertex {
private String name;
private int nodes;
public Vertex(String name) {
this.name = name;
nodes = 0;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Vertex other = (Vertex) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equalsIgnoreCase(other.name))
return false;
return true;
}
In my Graph class I wrote a method which returns the neighbours(nodes) of a specific vertex:
public List<Vertex> getNodesOf(Vertex v) {
List<Vertex> nodes = new ArrayList<>();
if (vertices.contains(v)) { //vertices is an ArrayList<Vertex>
// adds all neighbours to nodes...
return nodes;
} else {
Terminal.printLine("Error, " + v.getName() + " does not exist here!");
return nodes;
When I call that method from my main method, it works fine:
List<Vertex> nodes = g.getNodesOf(new Vertex(input[1])); //input[1] is a name typed by the user
if (nodes != null) {
for (Vertex node : nodes) {
System.out.println(node.getName());
}
}
But I have another class for the dijkstra-algorithm to find the shortest path. this algorithm also needs the neighbours. this is a part of the code:
Vertex nearest = null;
int distanceInt = 9999;
for (Vertex vertex : unvisited) {
if (distance.containsKey(vertex)) {
if (distance.get(vertex) <= distanceInt) {
nearest = vertex;
distanceInt = distance.get(vertex);
}
}
}
if (graph.getNodesOf(nearest).contains(vertex)) {
// do something...
}
But when i call the method from here, it always says that the ArrayList doesn´t contain the Vertex and the //do something... will never be reached.
I overrided the equals and hashcode method with eclipse, so i thought, this was not the problem.
What´s my mistake?
Your equals()-hashCode()-implementation is broken. The spec says that equal objects must have equal hash-codes. But in your equals()-method you ignore the case of names while the hash-method does not ignore it.
This behaviour is relevant if you use hash-based maps, and distance.containsKey(vertex) looks like a typical map-lookup so I assume that your distance-object is a kind of Map.
Solution: Make your hashCode()-method also case-insensitive, or make your equals()-method case-sensitive.

Why does my function always returns false, even if it finds return true before?

public boolean contains(Object data)
{
Node temp = new Node(data);
Node current = head.getNext();
for(int i = 0; i < size(); i++)
{
//System.out.println(current.getData());
if(temp.getData() == current.getData())
{
System.out.println("true");
return true;
}
else
{
current = current.getNext();
}
}
return false;
}
My code is above and it returns false no matter what. If it finds a true condition, it prints "true" and it still returns false. What am I doing wrong here? I have exact same function, except it's returning an integer instead of boolean and it works perfectly fine with the same method/code.4
My function which does the same and works fine:
public int indexOf(Object data)
{
Node temp = new Node(data);
Node current = head.getNext();
for(int i = 0; i < size(); i++)
{
if(temp.getData() == current.getData())
{
return i;
}
current = current.getNext();
}
return -1;
}
You've got an issue with this expression:
if(temp.getData() == current.getData())
It's bad enough that your data is represented by Object - it really should be a parameterized type* instead. But, since you're using ==, you're checking to see if the object is the same instance, not if they're equivalent.
Change your comparison to use .equals instead.
if(temp.getData().equals(current.getData())
*: In case you were wondering, you'd change your Node to a Node<T> instead, change your linked list instance to be typed to LinkedList<Node<T>>, and change the method argument of contains to be public boolean contains(T data).

Function to check if binary tree is BST is always returning true

I have written a recursive program for checking whether a binary tree is a BST.
I have written a base case which is returning true or false, but I have got confused in recursive case.
This program makes the recursive call but it is not working though I feel its fine.
public class BinaryBSTChecker {
public static boolean isBinaryBST(Node node) {
if ( node != null) {
Node leftNode = node.getLeftNode();
Node rightNode = node.getRightNode();
int value = node.getValue();
isBinaryBST(leftNode) ;
isBinaryBST(rightNode) ;
boolean leftIsOk = isLeftOK(leftNode , value);
boolean rightIsOk = isRightOK(rightNode, value);
return (leftIsOk && rightIsOk);
}
return false;
}
private static boolean isLeftOK(Node leftNode, int value) {
boolean leftOK = false;
if (leftNode != null) {
if (leftNode.getValue() < value) {
leftOK = true;
}
} else {
leftOK = true;
}
return leftOK;
}
private static boolean isRightOK(Node rightNode, int value) {
boolean rightOK = false;
if (rightNode != null ) {
if (rightNode.getValue() > value) {
rightOK = true;
}
} else {
rightOK = true;
}
return rightOK;
}
}
Client code:
public class TestingClient {
public static void main (String[] args) {
Node node = getBSTTree() ;
System.out.println("------Is Binary BST ?------>"
+ BinaryBSTChecker.isBinaryBST(node));
}
public static Node getBSTTree() {
Node node = new Node(9);
Node leftNode = new Node(7);
Node rightNode = new Node(11);
Node leftNode2 = new Node(67);
Node rightNode2 = new Node(8);
Node leftNode3 = new Node(10);
Node rightNode3 = new Node(12);
node.setLeftNode(leftNode);
node.setRightNode(rightNode);
leftNode.setLeftNode(leftNode2);
leftNode.setRightNode(rightNode2);
rightNode.setLeftNode(leftNode3);
rightNode.setRightNode(rightNode3);
return node;
}
}
The above tree isn't a BST as 67 > 7.
So this should return false, but I am getting true for this case, and in fact for all cases.
why are you returning false at end of public static boolean isBinaryBST(Node node) ?
Return true there and should be ok.
edit:
obviously it was a mistake but i did not take a good look at code.
One more thing here.
There is only isLeftOK and isRightOk called, but also on left & right nodes but there are also calls
isBinaryBST(leftNode) ;
isBinaryBST(rightNode);
It seems that results of those are ignored and this is an issue.
return should be sth like:
return (leftIsOk && rightIsOk && isBinaryBST(leftNode) && isBinaryBST(rightNode));
You're ignoring the return value of isBinaryBST in the recursive calls, so the function just returns whether the root's children is correct.
But the way you tried to solve the problem fundamentally won't work.
Take this tree:
5
/
3
\
7
It's not a valid BST, as 7 > 5.
There's no way you can check for this by only looking at the direct children.
The recommended approach would be passing in a min and max to your function, i.e. the signature would be:
boolean isBinaryBST(Node node, int min, int max)
And simply checking whether the current node's value is between the two (or the node is null) (no need for helper functions), and making the appropriate recursive calls to the children (and remember to check their return values!). The general idea would be: (pseudo-code)
return (current node is between min and max)
&& (left subtree is okay, i.e. recursive call with left child)
&& (right subtree is okay, i.e. recursive call with right child)
I'll leave the exact details to you to work out.
In the above example, when we get to 7, min = 3 and max = 5, so we see that 7 > max, and return false.
Add null checks or it will go in infinite loop
if(leftNode != null)
isBinaryBST(leftNode) ;
if(rightNode != null)
isBinaryBST(rightNode) ;
boolean leftIsOk = true;
boolean rightIsOk = true;
if(leftNode != null)
leftIsOk = isLeftOK(leftNode , value); ;
if(rightNode != null)
rightIsOk = isRightOK(rightNode, value);
return (leftIsOk && rightIsOk);

contains function linkedlist

public class state implements Comparator<state>{
Point a;
Point b;
private int path_cost=0;
...
}
class Point {
int x;
int y;
...
}
for above i have:
PriorityQueue<state> openNode= new PriorityQueue<state>();
LinkedList<state> closed =new LinkedList<state>();
state currNode;
I need to check if the Point a of ANY openNode or closed equals currNode's Point a.
I could use contains if i had to match the entire object but here i just care about one variabale (Point a) of state class. I want the method to check all the nodes in PriorityQueue and LinkedList.
addition:
I am thinking about using Iterator on my priorityQueue and LinkedList. But i am not sure how to read the value of Point a using Iterator.
EDIT: Looked like I'd misunderstood slightly. It's simpler than I thought.
// I've assumed more conventional names
Point currPoint = currNode.getPointA();
for (State openNode : openNodes) {
if (openNode.getPointA().equals(currPoint)) {
return true;
}
}
for (State closedNode : closedNodes) {
if (closedNode.getPointA().equals(currPoint)) {
return true;
}
}
// No matching points
return false;
You could potentially use Guava's Iterables.concat() method to make this slightly simpler:
for (State node : Iterables.concat(closedNodes, openNodes)) {
if (node.getPointA().equals(currPoint)) {
return true;
}
}
return false;
If you need to know which node has an equal point A, just change it to:
for (State node : Iterables.concat(closedNodes, openNodes)) {
if (node.getPointA().equals(currPoint)) {
return node;
}
}
return null;
That will only find one such node, of course - there may be multiple matches.
You will have to either provide equals method on Point a for state class or just use simple iteration and iterate over both List for comparison. contains method does the same.
If you use any other method it will be time consuming.
Very odd method is use Comparator to check equality
class PointAComparator implements Comparator<State>
{
Point p = null;
public PointAComparator(Point a) {
p = a;
}
#Override
public int compare(State o1, State o2) {
return (p.x == o1.a.x && p.y == o1.a.y) ? 1
: (p.x == o2.a.x && p.y == o2.a.y) ? 1 : -1;
}
}
Above compare method returns 1 for equal else -1 so when you do sorting then each list will have elements at the start which are equal. and then you can check for first element.
i used method overriding on function equals for both the object and achieved my result.
class Point {
int x;
int y;
...
#Override
public boolean equals(Object other){
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof Point))return false;
Point otherPoint = (Point)other;
return (this.x==otherPoint.getX() && this.y==otherPoint.getY() )? true : false;
}
}
public class state implements Comparator<state>{
Point a;
Point b;
private int path_cost=0;
...
#Override
public boolean equals(Object other){
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof state))return false;
state otherState = (state)other;
return ((this.a).equals(otherState.a))? true : false;
}
}

Comparing circular linkedlists equals method

public class LinkedList {
Object contents;
LinkedList next = null;
public boolean equals(Object item) {
return (this == item) || ((item instanceof LinkedList) && this.equals((LinkedList)item));
}
public boolean equals(LinkedList item) {
return myUtil.equals(this.contents, item.contents) && myUtil.equals(this.next, item.next);
}
}
public class myUtil{
public static boolean equals(Object x, Object y) {
return (x == y) || (x != null && x.equals(y));
}
}
main(){
LinkedList myList = new LinkedList();
myList.next = new LinkedList();
LinkedList head = myList.next;
myList.next = head;
}
I think i have created a circular linkedlist here. So what i have done is to overwrite the equals method to ensure that circular references are handled:
For some reason the LinkedList.equals doesnt seem to return...is it because of my circular linkedlist, or am i missing some conditions?
The primary problem with this code is that your comparison will not terminate upon circular reference, and will loop forever if all contents fields are equal. It will always continue to the next comparison, and since the next item is always there (as it's a circle) this will continue forever.
myUtil.equals(this.contents, item.contents) && myUtil.equals(this.next, item.next);
To solve this issue, the simplest method would be to add a boolean private 'visited' field to each List item. When you compare, set visited on each item after the comparison. If both are not visited and the same, then continue. If only one is visited, your lists are not identical. If both are visited, you've compared the reachable entirety of the list. Generally, having loops in your list are a bad idea, and there exist algorithms specifically to detect them. This can be a confusing topic. Here is a coverage of loop detection that may help you understand the issue further. Remember, if you use the visited field, you must unset all of them with another loop in your equals() to allow it to run again.
On another note, you do not initialize the contents field of your list nodes for the test. This is okay here, since they are initialized to null, but generally it is good practice to explicitly initialize all your fields.
Generally speaking, you also don't need the equals(Object item) override. Try
public boolean equals(LinkedList item){
if (this == item){
return true; // It's the same object
}
// Add some null checks here, I'm lazy
if (this.visited && item.visited && this.contents.equals(item.contents){
this.visited = false; //Unset
item.visited = false;
return true;
}
if (this.visited && !item.visited){
this.visited = false;
return false;
}
if (!this.visited && item.visited){
item.visited = false;
return false;
}
if (!this.visited && !item.visited && this.visited.contents.equals(item.contents){
this.visited = true;
item.visited = true;
boolean ret = this.next.equals(item.next);
this.visited = false;
item.visited = false;
return ret;
}
// Contents not equal
return false;
}
This backtracks and unsets with some basic recursion. I obviously haven't compiled this, but that's the gist of it, I think (I hope there aren't too many errors)
Two issues, first you do not have a circular linked list. The follow code creates 2 lists, list1.next = list2, list2.next = null. No circle created.
LinkedList myList = new LinkedList();
myList.next = new LinkedList();
LinkedList head = myList.next;
myList.next = head;
Second, if you DID have a circular linked list, the following would produce an infinite loop since there is no end condition reached this is because in a circular linked linked, next should never be null.
public boolean equals(Object item) {
return (this == item) || ((item instanceof LinkedList) &&
this.equals((LinkedList)item));
}
public boolean equals(LinkedList item) {
return myUtil.equals(this.contents, item.contents) && myUtil.equals(this.next, item.next);
}
To do this effectively you need to provide SOME mechanism to iterate the list in a non-circular fashion even if this mechanism is private and not exposed to other users. One way to do this would be to mark a single node as the "root".
return myUtil.equals(this.contents, item.contents)
&& myUtil.equals(this.next, item.next);
I would imagine that this is your issue as you suspected, when you perform the second expression of the && namely myUtil.equals(this.next, item.next); you enter the myUtil.equals method which performs this line:
return (x == y) || (x != null && x.equals(y));
Which in turn uses x's .equals() method, which will repeat the process for its item.next, and so on and so forth since you have a circularly linked list.
This will cause an infinite loop, this is because in the code:
public static boolean equals(Object x, Object y) {
return (x == y) || (x != null && x.equals(y));
}
The x.equals(y) will again invoke:
public boolean equals(LinkedList item) {
return myUtil.equals(this.contents, item.contents)
&& myUtil.equals(this.next, item.next);
}
But if you are performing myList1.equals(myList1), you will not get an infinite loop because the (x==y) in myUtils.equals() will return true so infinite loop will not happen if you compare same objects.
However when you compare different objects, you will enter into an infinite loop.
This is not a circular list issue, this is because of the code design you've chosen.
Finally completed my equals method implementation. For this I had to use additional checking tools by myself. I can't tell it is effective, but some extraordinary states are checked.
public boolean equals(Object o)
{
if(!(o instanceof CircularlyLinkedList))
return false;
CircularlyLinkedList<E> list=(CircularlyLinkedList<E>)o;
if(this==list)
return true;
if(size()!=list.size())
return false;
//tail element of this object
Node<E> thisTail=tail;
//tail element of list passing as parameter
Node<E> listTail=list.tail;
//checking if tail elements of both lists are the same or not. If not rotate list till equatation is provided for tails
if(!thisTail.equals(listTail))
{
listTail = equate(list);
if(listTail==null)
return false;
}
//Each element checking
for(int i=0; i<size(); i++)
{
thisTail=thisTail.next;
listTail=listTail.next;
if(!thisTail.equals(listTail))
{
listTail = equate(list);
listTail=tail;
i=0;
if(listTail==null)
return false;
}
}
return true;
}
And equate method:
private Node<E> equate(CircularlyLinkedList<E> list)
{
Node<E> thisTail=tail;
Node<E> listTail;
for(int i=0; i<list.size(); i++)
{
list.rotate();
listTail=list.tail;
//If full rotation completes then returns null
if(list.getRotation()==0)
{
return null;
}
if(thisTail.equals(listTail))
{
return nodeList;
}
}
return null;
}
getRotation method returns count of rotation operation and changes between 0 and size-1. I hope that it will become useful.

Categories

Resources