0

I want to detect when adding some items to the array list or when removing some item from it. Actually I have some code like below:

public class myClass {

    MyCustomArrayList<MyObject> al;

    public void method1() {

        al.add(myObject);        
        // Do other works
        al.remove(myObject)
        // Do other works
    }

    private void DoByEachAdd() {
        //I want array list call this method by adding each item to it.
        // It should be in this class because it is doing some works
        // related to this class. for example changing some private variables
    }

    private void DoByEachRemove() {
        // I want array list call this method by adding each item to it.
        // It should be in this class too.
    }

}

I know that array list has not the ability for having listener or some kind of notifications or events and if I want to detect add should have a custom array list. something like below class:

class MyArrayList<T> {
    private ArrayList<T> list;

    public MyList(){
        list = new ArrayList<>();
    ...
    }
    public void add(T t) {
        list.add(t) {
        //do other things you want to do when items are added 
    }
    public T remove(T t) {
        list.remove(t);
        //do other things you want to do when items are removed
}

(I get it from here)

So the question is that: how can I inform the object of MyArrayList (al) that call DoByEachAdd and DoByEachRemove methods when the remove and add method fired. Does some body have any ideas?

Community
  • 1
  • 1
Husein Behboudi Rad
  • 5,344
  • 10
  • 55
  • 114

3 Answers3

1

First, follow naming convention. Second, the three class names you used for the same class, MyList, MyArrayList and MyCustomArrayList will confuse people. As for your question, you would have to have an instance field inside MyArrayList of type myClass (unless you want to refactor DoByEachAdd and DoByEachRemove to be static). This can be done by adding it as a constructor parameter, e.g.

// inside MyArrayList
private ArrayList<T> list;
private final myClass instance;

public MyArrayList(myClass instance) { // <-- NOT MyList
    list = new ArrayList();
    this.myClass = myClass;
}

Also, I question your approach. Other classes with instances of MyArrayList can only use the add and remove methods of ArrayList. If you want to save a lot of bother and have all methods visible, either declare list as public final or make MyArrayList a subclass of ArrayList, e.g.

public class MyArrayList<T> extends ArrayList<T> {
    private final myClass instance;

    public MyArrayList(myClass instance) { // <-- NOT MyList
        list = new ArrayList();
        this.myClass = myClass;
    }

    @Override
    public boolean add(T t) {
        boolean returnThis = super.add(t);
        // do some stuff
        instance.DoByEachAdd();
        return returnThis;
    }

    @Override
    public boolean remove(T t) {
        boolean returnThis = super.remove(t);
        // do some stuff
        instance.DoByEachRemove();
        return returnThis;
    }
}

If you insist on being able to return a T from remove, declare another method:

public T removeT(T t) {
    remove(t);
    // do some stuff
    return someT;
}
bcsb1001
  • 2,686
  • 3
  • 23
  • 34
0

you need to give access to your myClass to MyArrayList

class MyArrayList<T> {
    private ArrayList<T> list;
    private myClass theClass;

public MyList(myClass theClass){
    list = new ArrayList<>();
    this.theClass = theClass;
...
}
public void add(T t) {
    list.add(t) {
    //do other things you want to do when items are added 
    theClass.DoByEachAdd();
}
public T remove(T t) {
    list.remove(t);
    //do other things you want to do when items are removed
    theClass.DoByEachRemove
}

and in your myClass give the object to your list

public class myClass {

   MyCustomArrayList<MyObject> al;


 public myClass(){

  al = new MyCustomArrayList<MyObject>(this);

 }
public void method1() {

    al.add(myObject);        
    // Do other works
    al.remove(myObject)
    // Do other works
}

public void DoByEachAdd() {
    //I want array list call this method by adding each item to it.
    // It should be in this class because it is doing some works
    // related to this class. for example changing some private variables
}

public void DoByEachRemove() {
    // I want array list call this method by adding each item to it.
    // It should be in this class too.
}

}
Ker p pag
  • 1,578
  • 12
  • 25
0

You will probably need to use the Callback mechanism.

Java provides the callback mechanism with interfaces using the following steps:

  1. An interface is defined with an abstract method whose name is known to the server.

  2. Each client that has actions to be performed when a server event occurs implements the interface, thereby giving code for the abstract method.

  3. When a client registers with the server, the server holds an instance variable that refers to the client and whose type is the interface type.

  4. The server class invokes the client action by calling the interface method for that client.

Refer the following code and modify it to suit your requirements : The code is for a credit-card app simulation. The requirement is similar to yours,that is,Trigger some method automatically on the call of some method.In the below code, the pinChanged() method gets called automatically when the changePin() method is called.

public interface PinChangeListener {
    public void pinChanged();
}

public CreditCard {
    public PinChangeListener pinChangeListener;

    private int pin;

    public changePin(int pin) {
        this.pin = pin;
        if (pinChangeListener != null) {
            pinChangeListener.pinChanged();
        }
    }
}

To connect a callback/listener to the credit card you just need to implement the PinChangeListener method:

creditCard.pinChangeListener = new PinChangeListener() {
    public void pinChanged() {
        System.out.println("The pin has been changed");
    }
};
Sagar D
  • 3,118
  • 1
  • 17
  • 33