0

Below is sample code.

How to remove a specific element in ArrayList?


import java.util.ArrayList;

class A {
    int value;

    public A(int newValue) {
        setValue(newValue);
    }

    public int getValue() {
        return value;
    }

    public void setValue(int newValue) {
        value = newValue;
    }
}

class B {

    ArrayList <A> valuesOfA = new ArrayList<>();
    valuesOfA.add(new A(5));
    System.out.println("Adding...");
    for (A value: valueOfA) {
        System.out.println(value); //prints the values added.
    }
    valuesOfA.remove(new A(5));
    System.out.println("Removed");
    for (A value: valueOfA) {
        System.out.println(value);
    }
}

Element as still not been removed. What is the solution for this?

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 3
    Because you're not removing the same object, you're removing a brand new one. Lookup equals() and hashcode(). These define object equality. – Stewart May 30 '20 at 08:09
  • [ArrayList#remove](https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/ArrayList.html#remove(java.lang.Object)) – Seelenvirtuose May 30 '20 at 08:11
  • Do you want to remove a specific instance of `A` that you created before or do you want to remove one or more `A`s based on one or more of their attribute values? – deHaar May 30 '20 at 08:19
  • I'm looking to remove a specific instance. – Sampreeth Amith May 30 '20 at 08:23
  • You wrote in your question: _remove() works for primitive datatypes_ Java does not allow creating an `ArrayList` of primitives. Refer to [Autoboxing and Unboxing](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html) – Abra May 30 '20 at 08:35
  • https://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java – matt May 30 '20 at 10:50

3 Answers3

1

Redefine Class A like this:

Class A
{
    int value;
    public A(int newValue)
    {
        setValue(newValue);
    }
    public int getValue()
    {
         return value;
    }
    public void setValue(int newValue)
    {
         value = newValue;
    }
    public boolean equals(Object o)
    {
         if( o instanceof A)
         {
             return this.value == ((A)o).value;
         }
         return super.equals(o);
    }
}

By overriding this method, which uses the object's memory address by default, you are defining how two object should be considered the same.

You should also define the hashcode() method.

Stewart
  • 17,616
  • 8
  • 52
  • 80
  • 1
    _You should also define the `hashcode()` method_ Maybe you could [edit] your answer and provide an example implementation? – Abra May 30 '20 at 08:37
1

In Java every Class is extending Object at some point. Object got a method equals() which every class inherits. You should overwrite it to check if the passed object is equal to the current one.

It would solve your problem with the List. Lets take a look at the ArrayList.remove() JavaDoc - It says:

removes the element with the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))) (if such an element exists).

ArrayList goes through every entry in the List and calls the equals() method of it to compare it to the passed Object. So you could append your Class A by overriding the equals method and let it check on some kind of attribute to make sure it's the same Object. You could also implement some other way to make sure the Objects are equal, like generating a hashcode and compare those or the actual object ID.

An example on how you could implement such a way on your Class A:

Class A
{
    int value;
    public A(int newValue)
    {
        setValue(newValue);
    }
    public int getValue()
    {
         return value;
    }
    public void setValue(int newValue)
    {
         value = newValue;
    }
    @Override
    public boolean equals(Object obj) 
    {
        if(obj != null && obj instanceof A)
        {
            A tmp = (A)obj;
            if(tmp.getValue() == this.value) return true;
            else return false;
        }

        return false;
    }
}
vMysterion
  • 165
  • 3
  • 17
  • From the _javadoc_ of method `equals()`: _Note that it is generally necessary to override the `hashCode` method whenever this method is overridden, so as to maintain the general contract for the `hashCode` method, which states that equal objects must have equal hash codes_ – Abra May 30 '20 at 08:40
0

Though you are initializing the new object of A with same value, the objects are different having different memories, so you just have to remove the existing object having that memory location only.

I would suggest you to traverse the array and find the value 5 by filtering it and then removing that element from the array.

You could just use filter method for removing the added object. Your code would look something like this:

valuesOfA = valuesOfA.stream().filter(obj -> !obj.getValue().equals(5));

Now your valuesOfA array is not having the object whose value was 5 that you added before

Minal Shah
  • 1,402
  • 1
  • 5
  • 13