contains function linkedlist - java

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;
}
}

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.

How do I change what it means for objects to be duplicate in a set?

I want to store a set of Edges:
class Edge {
int u;
int v;
char symbol;
}
The problem is that it's possible for two Edge objects to have the same u, v and symbol, but they can both be stored in a HashSet because they're not the same object even though I want them to be considered the same object. How can I store only one object that has a unique (u, v, symbol) in a Set?
You need to override the following two methods equals and hashcode.
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Edge)) return false;
// return true if they are the same, otherwise false
}
public int hashCode() {
// return an int that represents similarity
// Example: name.hashCode(), if they are the same with the same name
}
Depends on what kind of set you want to use; The below applies for HashSet for instance, but not for any subclass of SortedSet
By overriding equals() and hashCode():
class Edge {
int u;
int v;
char symbol;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + symbol;
result = prime * result + u;
result = prime * result + v;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Edge other = (Edge) obj;
return symbol == other.symbol && u == other.u && v == other.v;
}
}
You have to override equals(). Like this:
public boolean equals(Object obj) {
//do the comparison here; remember to cast obj to Edge
}

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.

HashSet does not seem to realize that two objects are the same.

I'm trying to use HashSet to store objects of a class that I created, but apparently the same objects seem to have two different hashes, which is why the contains method does not realize that the object is already in the HashSet. This leads to my program running out of heap memory.
I don't think I'm doing anything wrong, but I wanted a second opinion anyway. I've done similar operations before which all worked fine, which makes this particularly annoying. I'd appreciate any help.
Here's my code
move1 = new Move(t,s);
if(move1.hashCode()==new Move(t,s).hashCode())
System.out.println("match");
move2 = new Move(s,t);
moves.add(move1);
moves.add(move2);
if(moves.contains(new Move(t,s)))
System.out.println("match found");
Here's the Move class:
public class Move {
private int move1;
private int move2;
Move(int m1, int m2)
{
move1 = m1;
move2 = m2;
}
public String toString()
{
return String.valueOf(move1)+" "+String.valueOf(move2);
}
}
Here's the output I get
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.HashMap.addEntry(HashMap.java:797)
at java.util.HashMap.put(HashMap.java:431)
at java.util.HashSet.add(HashSet.java:194)
at makeMove.<init>(makeMove.java:33)
You need to override the Object#hashCode() method in the Move class to let it return the same hashCode() value for the state of the Move instance. Don't forget to override Object#equals() as well.
See also:
Overriding equals and hashCode in Java
Hint: if you're using an IDE like Eclipse, you can also just autogenerate them. Rightclick somewhere the Move class, choose Source > Generate hashCode() and equals(). Here is how it look like then:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + move1;
result = prime * result + move2;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Move other = (Move) obj;
if (move1 != other.move1)
return false;
if (move2 != other.move2)
return false;
return true;
}
HashSet will determine equality based on calling hashCode() and equals(). You have not implemented these, so you'll inherite them from Object. The hashCode and equals methods of Object is just based on whether the references are equal.
That's why if(move1.hashCode()==new Move(t,s).hashCode()) is false. move1 is a different instance than the instance created by calling new Move(t,s).hashCode()
You'll need to implement hashCode and equals in your Move class.
e.g.(though perhaps non-optimal, and you might want a null safe equals - have your IDE generate them if it can)
public int hashCode() {
return move1 ^ move2 +;
}
public boolean equals(Object o) {
if(!other instanceof Move)
return false;
Move other = (Move)o;
return other.move1 == move1 && other.move2 == move2;
}
You have to override equals() and hashCode().
This may be an option.
import static java.lang.System.out;
public class Move {
private int move1;
private int move2;
Move(int m1, int m2) {
move1 = m1;
move2 = m2;
}
public String toString() {
return String.valueOf(move1)+" "+String.valueOf(move2);
}
public int hashCode() {
return move1 * 31 + move2 * 31;
}
public boolean equals( Object other ) {
if( this == other ) { return true; }
if( other instanceof Move ) {
Move m2 = ( Move ) other;
return this.move1 == m2.move1 && this.move2 == m2.move2;
}
return false;
}
public static void main( String [] args ) {
out.println( new Move(2,3).equals( new Move(2,3)));
out.println( new Move(1,1).hashCode() == new Move(1,1).hashCode() );
}
}
You have to define if the order of the move is relevant ( 1,2 isequals to 2,1 or not )
For more information:
What issues should be considered when overriding equals and hashCode in Java?

Java: Problems with TreeSet

I have a class Odp. I want to use TreeSet to keep a sorted collection of Odp objects. However, I've been having problems.
public class OdpStorage {
private TreeSet<Odp> collection = new TreeSet<Odp>();
public addOdp(Odp o) {
return collection.add(o);
}
public int size() {
return collection.size();
}
}
collection.add(Odp o) is supposed to do nothing if it's already in the tree, right? Somehow, this unit test fails:
OdpStorage ts = new OdpStorage();
Odp ftw = new Odp("LOL");
Odp ktr = new Odp("OMG");
ts.addOdp(ftw);
ts.addOdp(ftw); //should do nothing
ts.addOdp(ftw); //should do nothing
ts.addOdp(ftw); //should do nothing
ts.addOdp(ktr);
assertEquals(2, ts.size());
The assertion fails. It expects 2, but the return value is 5. Why? Could the odp.equals() function be messed up?
Similarly, calling collection.contains(o) fails, even when the there is an object in the set X for which o.equals(X) returns true.
The .equals() function of Odp: (generated by Eclipse)
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Odp))
return false;
Gene other = (Odp) obj;
if (sequence == null) {
if (other.sequence != null)
return false;
} else if (!sequence.equals(other.sequence))
return false;
return true;
}
compareTo:
/**
* this = g0
* if they are equal, g1 is presumed to come first
*
* #return -1 if g0 comes before g1; 1 if g0 comes after g1
*/
#Override
public int compareTo(Odp g1) {
if (sequence.length() < g1.getSeq().length()) {
return -1;
}
else if (sequence.length() > g1.getSeq().length()) {
return 1;
}
if (sequence.compareTo(g1.getSeq()) < 0) {
return -1;
}
return 1;
}
hashCode() is not overridden. Problem?
UPDATE
hashCode() is as follows:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((sequence == null) ? 0 : sequence.hashCode());
return result;
}
But that still doesn't solve the problem.
Your compareTo implementation never returns 0. It should return 0 when the object instances are equal.
It appears that your collection.add(o) is failing to find the object in the backing TreeMap. Does your Odp implement Comparable or are you setting a default Comparable on your TreeSet whose compare method you have implemented? If so, you will need to ensure that your compareTo (for the Comparable), or your Comparator compare method will return 0 if the objects passed in are equals.
EDIT (in response to your comment to the original post):
It is recommended that you override HashCode() whenever you override equals()
EDIT2 in response to your compareTo implementation:
If g0 and g1 are equal, you should return 0. This is the root of the problem.
Mate cleanup your equals, its got too many if/elses. replace it with a nice do/while with lots of condition tests. If all the tests pass then reutrn true...Yes its got "goto" statements but its very easy to read and even easier to insert new conditions as necessary without lots of nesting. Nesting if/elses is evil. Using "elses" is evil and almost always never needed.
#Override
public boolean equals(final Object object) {
boolean equals = false;
do {
if (this == object) {
equals = true;
break;
}
if (false == super.equals(object)) {
break;
}
final DocumentView view = Unsafe.cast(object);
if (false == this.document.equals(view.document)) {
break;
}
if (this.revision != view.revision) {
break;
}
if (false == this.user.equals(view.user)) {
break;
}
if (false == this.timestamp.equals(view.timestamp)) {
break;
}
equals = true;
} while (false);
return equals;
}

Categories

Resources