Java HashSet 2d array duplicate recognition - java

I need to check whether a list/set of 2d char arrays contains an exact duplicate of another 2d char array that I pass as a parameter. My idea was to make a HashSet and then use the contains() method, but that's not really working; I assume it has to do with me passing the method 2D arrays. If possible, I don't want iterate through every item in the list because that is too costly. Please help me out here. Thanks!

That would never work because the hashCode of the arrays is based on the Object's so unless you are trying to find same references, you will never get a contains to evaluate to true.
You should create a wrapper for your arrays and override the hashCode and equals. You can use Arrays.deepEquals for this purpose

Related

At which point array class is being created in java?

Today I tried to compare two arrays using equals(), it obviously failed, I started diggin' etc etc, and after some research I can't quite figure out: at which point in time the class for an array is being created? Cuz I know that int [] a leads to creation of an array class for integers. Who creates it? Why it was impossible to override Object.equals() so that it doesn't compare two objects and compares elements of arrays instead? Would be very grateful if someone could explain or provide a link, which would help to understand that.
Array doesn't override equals() of the Object class.
So it will not use the equals() method of the objects that it holds when equals() is invoked on an Array.
If you want to compare two arrays of integer, you can use Arrays.equals() method.
If it doesn't suit you, create your own method to compare two array of integers.
But overriding equals() of Array is not possible as the class is final and besides it seems rather a weird approach.

Use of equals() method in HashSet

I read somewhere that equals() method is used to determine if two objects in HashSet are considered to be same or not.I am bit confused with my understanding.Can anyone explain the scenario please. Thanks in advance.
equals is used to determine if the object you are trying to add or search for already exists in the HashSet. It's not used to determine if two objects in the HashSet are considered the same, since two such objects can't both be in the HashSet.

ArrayList<int[]> containing a value

if i have an ArrayList<int[]> example and I want to check if {2,4} is in it how would I do this?
exaple.contains({2,4}); //doesn't work
and
exaple.contains(2,4); //doesn't work either
what is wrong with the code?
Arrays don't override the Object.equals() method (that ArrayList.contains() uses to compare objects). So an array is only equal to itself. You'll have to loop through the list and compare each element with your array using Arrays.equals().
What I suspect, though, is that you shouldn't have a List<int[]>, but a List<Coordinate>. The Coordinate class could then override equals() and hashCode(), and you would be able to use
example.contains(new Coordinate(2, 4))
You could also use a List<List<Integer>>, but if what I suspect is true (i.e. you're using arrays to hold two coordinates that should be in class), then go with the custom Coordinate class.
Even if you did it properly, ie:
int[] vals = {2, 4};
exaple.contains(vals);
You would not return true, because the contains method will use the equals method. Unless you have overridden the equals method, then this will always resolve to false, unless you pass in the exact same array.
You might want to take a look at this. And please post a bit of you're code.
i need to find a integer data in arraylist?
The contains() method checks, if ArrayList contains a specific object, it doesn't concern itself with the values inside an object. In other words, if you instantiate two {2,4} arrays, it will be two different objects and contains() method will diferentiate between them.
What you need to do is either override the contains() method to look on the content of arrays, instead of only the reference, or you can drop the contains() method completely and check it by hand.

HashSet returns true when contains the object no matter the contents changes or not

I know it may be a naive problem but I'm really in need of help!
When I use HashSet and used it within some function that at some point, the
content char[][] may be changed. I want to use the HashSet to check whether or not it contains the value but every time it return true no matter the value changed or not.
for example:
HashSet<char[][]> visited = new HashSet<char[][]>();
char[][] board = Board.board // initialization;
visited.add(board);
for(int i = 0; i < 4; i++){
if(visited.contains(board)
System.out.println("Why");
}
Here is the problem! Each time it returns "true" no matter no the board changes its contents;
Anyone can help??
I saw the comments and thanks for replying. The char[][] board is a map and I want to find a path
on the map. The "for" loop is actually the search algorithm which find path from 4 direction. So each time the contents of the board is going change and I want to shorten the duplicates. That's why I used hashset to store the paths or maps I already traveled.
HashSet internally uses the hashCode and equals methods to tell if two objects are equal. For arrays, hashCode and equals don't look at the contents of the array. Instead, they just produce a hash code based on the identity of the object, and two arrays compare equal if and only if they're the same object. This means that if you put an array into a HashSet and then try looking up that array after changing the contents, it will always find it.
Another detail here is that you put the array into the HashSet and then change the contents of the array externally, since the array is an object, you're also changing the copy of the array you put into the HashSet in the first place!
To fix this, I'd suggest defining a wrapper class around the array and then overriding equals and hashCode to check for equality based on the contents of the array and to compute a hash code from the contents.
Hope this helps!

Map's equals() for keys that are arrays

I'm using a TreeMap (SortedMap) whose keys are Object[] with elements of varying types.
TreeMap's equals() doesn't work on Object[] like Arrays's equals() would do -- which means it won't work when using its methods like containsKey() and get() unless I workaround it.
Is there somewhere a solution for this that doesn't involve creating a whole new Class?
EDIT :
Just to make it clear, I made a mistaken assumption. Creating a new Comparator(){} also does affect every method that uses equality, such as equals(), not only the tree sorter.
Is there somewhere a solution for this that doesn't involve creating a whole new Class?
No. In fact, you shouldn't be using mutable values for map keys at all.
While I agree with Matt Ball that you generally shouldn't use mutable (changeable) types as your keys, it is possible to use a TreeMap in this manner as long as you are not planning on modifying the arrays once they are in the tree.
This solution does involve the creation of a class, but not a new Map class, which is what it seems you are asking. Instead, you would need to create your own class which implements Comparator<Object[]> that can compare arrays. The class could use the Arrays.equals() method to determine if they are equal, but would need to also have a consistent rule to determine which array comes before another array when the arrays are not equal.

Categories

Resources