Mushroomzier
Mushroomzier

Reputation: 108

ArrayList.Remove does not work the first time invoked

I Have an ArrayList<String> that I use to store PackageInfo(an example of an element in the arraylist is "com.skype.raider").

The arralist is initialized as follows:

    private List<String> pkgs;

And In The Class Consturctor

    pkgs = new ArrayList<>();

When i invoke pkgs.remove(String), it doesn't work, but when i repeatedly try and remove, it eventually works.

Heres how i test if removal worked( i edited the code so it reads more easily)


private void togglePackage(String selectedPackage,CheckBox chk_app){

    String m_pkg = selectedPackage.toString(); //redundant .toString()
    boolean checked = !chk_app.isChecked(); //checkbox boolean toggle

    if (checked && !pkgs.contains(m_pkg)) { //if not already in arraylist
        pkgs.add(m_pkg); //adding the newly checked package
    } else if (!checked && pkgs.contains(m_pkg)) { //if it needs to be removed
        pkgs.remove(m_pkg); //<-----------------------This works around the 3rd time i press the checkbox
    }
    //Here i check if the string was actually removed from the arrylist
    //This following code will not be in production, i just used it for testing

    if (pkgs.contains(m_pkg)) {
        if (checked) {
            chk_app.setChecked(checked);//Success
        } else {
            chk_app.setChecked(!checked);//Failure
        }
     } else {
         if (!checked) {
            chk_app.setChecked(checked);//Success
         } else {
            chk_app.setChecked(!checked);//Failure
         }
     }
 }

Here is the unedited onclick event

RelativeLayout rl_container = (RelativeLayout) child.findViewById(R.id.rl_container);
               rl_container.setTag(pkg);
               rl_container.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String m_pkg = v.getTag().toString();
                        System.out.println("Pkg = "+m_pkg);
                        boolean checked = !chk_app.isChecked();
                        if (checked && !pkgs.contains(m_pkg)) {
                            pkgs.add(m_pkg);
                            System.out.println("Adding " + m_pkg);
                        } else if (!checked && pkgs.contains(m_pkg)) {
                            pkgs.remove(m_pkg);
                            System.out.println("Removing " + m_pkg);
                        }


                        if (pkgs.contains(m_pkg)) {
                            if (checked) {
                                System.out.println("Success");
                                chk_app.setChecked(checked);
                            } else {
                                System.out.println("Fail");
                                chk_app.setChecked(!checked);
                            }

                        } else {
                            if (!checked) {
                                System.out.println("Success");
                                chk_app.setChecked(checked);
                            } else {
                                System.out.println("Fail");
                                chk_app.setChecked(!checked);
                            }
                        }


                    }
                });

As an example i have included the arraylists contents that i got by iterating over the list. as well as the log output of my tests

List contents:

com.sbg.mobile.phone

com.google.android.youtube 

com.e8tracks 

com.vlingo.midas 

com.google.android.googlequicksearchbox 

com.truecaller 

Logcat output from unedited code when i try to deselect "com.sbg.mobile.phone"

12-18 10:37:25 ViewPostImeInputStage ACTION_DOWN
12-18 10:37:25 Pkg = com.sbg.mobile.phone
12-18 10:37:25 Removing com.sbg.mobile.phone
12-18 10:37:25 Fail
12-18 10:37:28 ViewPostImeInputStage ACTION_DOWN
12-18 10:37:28 Pkg = com.sbg.mobile.phone
12-18 10:37:28 Removing com.sbg.mobile.phone
12-18 10:37:28 Fail
12-18 10:37:30 ViewPostImeInputStage ACTION_DOWN
12-18 10:37:31 Pkg = com.sbg.mobile.phone
12-18 10:37:31 Removing com.sbg.mobile.phone
12-18 10:37:31 Fail
12-18 10:37:32 ViewPostImeInputStage ACTION_DOWN
12-18 10:37:32 Pkg = com.sbg.mobile.phone
12-18 10:37:32 Removing com.sbg.mobile.phone
12-18 10:37:32 Fail
12-18 10:37:33 ViewPostImeInputStage ACTION_DOWN
12-18 10:37:33 Pkg = com.sbg.mobile.phone
12-18 10:37:33 Removing com.sbg.mobile.phone 
12-18 10:37:33 Success

PS. This is my first question, so be gentle. I would also appreciate any advice on how to improve on asking questions ,I tried to include all of the required info, but if you need anything else, please let me know.

Upvotes: 6

Views: 192

Answers (3)

Sandy
Sandy

Reputation: 166

Problem is in your condition. Condition should be like:

    if (checked) {
        if (!pkgs.contains(m_pkg)) {
            pkgs.add(m_pkg);
        }
    } else {
        if (pkgs.contains(m_pkg)) {
            pkgs.remove(m_pkg);
        }
    }

you can refer to the links:

Adding/Removing Strings in an ArrayList<String> by Checkbox

How to Handle the checkbox ischecked and unchecked event in android

Upvotes: 1

S. K
S. K

Reputation: 170

Let's consider ArrayList default behaviour:

ArrayList of strings have 5 elements. If you remove element at 2nd position then arraylist will become set of 4 elements and 3rd element now at 2nd position. Now when you remove 5th element but its position is changed now.

So use Arraylist of hashmap and when you want to remove elements from arraylist, you should iterate all elements of arraylist and remove particular element from it.

OR if you want only checked items when some event (like button press) occers then get only that checked items from adapter of list.

Upvotes: 2

RexSplode
RexSplode

Reputation: 1505

I think it might be a problem, because ArrayList gives you an opportunity to store equal objects multiple times. Maybe, it is a good idea to use HashSet<String> instead?

 private Set<String> pkgs;

Upvotes: 6

Related Questions