3

I have a Map in Java like so,

private HashMap<String, Object[][]> theMap;

Where the key is a String and the entry is going to be something along the line of,

theMap = new HashMap<>();

Object[][] theData = {
    {Boolean.FALSE, "Text"}
};

theMap.put("Key1", theData);

Somewhere along the line I would like to check if an entry in the map is equivalent to another object. Currently I am doing it like this,

Object[][] tempData = {
    {Boolean.FALSE, "Text"}
};

for(Object key: entries.keySet()) {
    if(entries.get(key).equals(tempData)) {
        entries.remove(key);
    }
}

And it is not working.

I would prefer the comparison to be done with an object rather than with another map. I'm wondering what I'm doing wrong with this comparison here?

Kyleryan19
  • 35
  • 2
  • 2
    Basically the problem here to compare two 2D arrays, you can use this : Arrays.deepEquals(array1, array2); – Mouad EL Fakir Feb 17 '17 at 23:48
  • And for the for loop use values instead of keys.(for(Object value:entries.values()) Makes the code cleaner –  Feb 17 '17 at 23:53
  • By the way since you are removing entries as you go maybe you should use an Iterator. –  Feb 17 '17 at 23:55

2 Answers2

3

The reason you are not getting equality is that arrays inherit Object#equals() which is based on identity, not equality of contents. You could consider using java.util.Arrays.deepEquals(Object[], Object[]) to compare.

That is the answer to the immediate question. However, using a 2-dimensional array of Object to hold a boolean and a String is really bad code smell and indicates you need to encapsulate what you are putting in the array.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • This did solve my problem, thank you. And what would your suggestion be to change how I'm holding onto my data other than an object? – Kyleryan19 Feb 17 '17 at 23:52
  • Yes absolutely. But that will require understanding what you're trying to store in the map to design an appropriate class. Give it a shot yourself and don't forget to implement `hashCode()` and `equals()` appropriately. If you end up having problems doing that post a new question. – Jim Garrison Feb 17 '17 at 23:53
1

Identity vs Equivalence

Please make sure that you understand that by default the equals() method of Object checks on whether two object references are referring to the same object (identity), which is not what your code is checking.

Instead, your code is checking whether the two objects (the values you put on the map) are having the same value (equivalence).

Here are two articles about this topic:

  1. What is the difference between identity and equality in OOP?
  2. Overriding equals method in Java

In this particular problem of yours, I think the solution involves two steps:

  1. Your tempData and theData does not seems to be an array of elements of the same type (it does not appear to be a 2-dimensional array either). Instead, it contains a Boolean value and then a String value. In this case, I think you really should think through what this thingy is and design a class for it (I am showing an example below)
  2. The class should override the equals() (and hashCode()) methods so that you can use its equals() for equivalence checking.

Note also that your IDE (e.g. Eclipse) probably can generate a template for equals() and hashCode() for you.

Example: (here I assume your Boolean represents a condition, and your String represents a message)

class MyRecord {
    private Boolean condition;
    private String  message;
    public Boolean getCondition() {
        return condition;
    }
    public void setCondition(Boolean condition) {
        this.condition = condition;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((condition == null) ? 0 : condition.hashCode());
        result = prime * result
                + ((message == null) ? 0 : message.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;
        MyRecord other = (MyRecord) obj;
        if (condition == null) {
            if (other.condition != null)
                return false;
        } else if (!condition.equals(other.condition))
            return false;
        if (message == null) {
            if (other.message != null)
                return false;
        } else if (!message.equals(other.message))
            return false;
        return true;
    }
}
Community
  • 1
  • 1
leeyuiwah
  • 6,562
  • 8
  • 41
  • 71