-1

Each x seconds, I check for new data from a server in my Android App. If some new data is available, I need to add it to an ArrayList only if that data is not present already in that ArrayList.

By reading other questions similar to this, I came to understand that I need to use .contains() on ArrayList by overriding the .equals() and .hashcode() in the model.

So my model looks like this:

class Order {
    String tavolo;
    String ora;

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    Order(String tavolo, String ora){
        this.tavolo = tavolo;
        this.ora = ora;
    }

    public String getOra() {
        return ora;
    }

    public String getTavolo() {
        return tavolo;
    }

    public void setOra(String ora) {
        this.ora = ora;
    }

    public void setTavolo(String tavolo) {
        this.tavolo = tavolo;
    }
}

And the method where I check if the item exists in the ArrayList already(and if not, add it to the ArrayList) looks like this:

public ArrayList<Order> ordini;
public void VisualOrder(){
    Ion.with(getApplicationContext())
            .load("GET", "https://visualorder.it/api/ordine/13/00168780351/")
            .asJsonArray()
            .setCallback(new FutureCallback<JsonArray>() {
                @Override
                public void onCompleted(Exception e, JsonArray result) {
                    if(result != null && result.size() > 0){
                        badgeOrders.setNumber(result.size());
                        result.forEach(ordine -> {
                            Order order = new Order(ordine.getAsJsonObject().get("tavolo").toString(), ordine.getAsJsonObject().get("dataora").toString());
                            if(!ordini.contains(order)){ // Check if order is yet in ArrayList
                                ordini.add(order); // if not add to ArrayList
                                adapterOrdini.notifyDataSetChanged();
                            }
                        });
                    }
                }
            });
}

But !ordini.contains(order) returns true everytime, even if I'm adding an item that already exists in the ArrayList.

So how do I add the item to ArrayList only if the item is not present already in that list?

Ayush
  • 916
  • 5
  • 21
NiceToMytyuk
  • 2,262
  • 17
  • 47
  • 2
    That is not how you override equals(). Your implementation checks if they are exactly the same objects. You need to check if they are equal, eg. check if all their properties are equal. You should use some IDE that would generate good enough implementation for you (like Intellij). – Amongalen Jun 24 '20 at 06:55
  • 1
    *"by overriding the `.equals` and `.hashcode`"* --- The purpose of overriding those methods is to **change their behavior**, not just make them do what they already did. – Andreas Jun 24 '20 at 06:58
  • Oh, and to add to my previous comment - you need a proper implementation for `hashcode` as well, not only `equals`. – Amongalen Jun 24 '20 at 06:59
  • What Igor said. We can use .contains() to check if an item exists, if we have provided the implementation of .equals() and .hashCode(), otherwise object reference will be used for equality comparison(And your implementation is checking for references as well, so change that). Also in case of a list, .contains() is O(n) operation where as it is O(1) for HashSet so it's better to use the latter. – Ayush Jun 24 '20 at 07:05

1 Answers1

1

You need to override your equals and hashcode method, like this:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Order order = (Order) o;
    return Objects.equals(tavolo, order.tavolo) &&
            Objects.equals(ora, order.ora);
}

@Override
public int hashCode() {
    return Objects.hash(tavolo, ora);
}
Brian H.
  • 1,267
  • 5
  • 14