【问题标题】:ArrayList.Remove does not work the first time invokedArrayList.Remove 在第一次调用时不起作用
【发布时间】:2015-12-18 17:41:14
【问题描述】:

我有一个 ArrayList<String> 用于存储 PackageInfo(arraylist 中的一个元素示例是“com.skype.raider”)。

arralist 初始化如下:

    private List<String> pkgs;

在类构造函数中

    pkgs = new ArrayList<>();

当我调用pkgs.remove(String) 时,它不起作用,但当我反复尝试删除时,它最终起作用了。

以下是我如何测试删除是否有效(我编辑了代码,以便更容易阅读)


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
         }
     }
 }

这是未编辑的 onclick 事件

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);
                            }
                        }


                    }
                });

作为一个例子,我已经包含了我通过迭代列表获得的 arraylists 内容。 以及我的测试的日志输出

列表内容:

com.sbg.mobile.phone

com.google.android.youtube 

com.e8tracks 

com.vlingo.midas 

com.google.android.googlequicksearchbox 

com.truecaller 

当我尝试取消选择“com.sbg.mobile.phone”时,未编辑代码的 Logcat 输出

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。这是我的第一个问题,所以要温柔。 我也很感激任何关于如何改进提问的建议,我试图包含所有必需的信息,但如果您需要任何其他信息,请告诉我。

【问题讨论】:

  • 您确定您的 ArrayList 在您第一次尝试删除它时包含给定的字符串吗?
  • int position = pkgs .indexOf("yourtext");然后 pkgs .remove(position );
  • 不明白为什么要使用“isChecked”来验证字符串是否仍在数组中...您应该只使用pkgs.contains(...),其他什么都不重要。
  • @mithrop 我并没有真正使用 isChecked 来验证它是否仍在数组列表中,我只是用它来衡量我试图实现的目标的成功或失败。
  • @koutuk 我尝试使用位置,但似乎没有解决它,而是使用 HashSet 代替工作

标签: java android arraylist


【解决方案1】:

我认为这可能是个问题,因为ArrayList 让您有机会多次存储相同的对象。也许,改用HashSet&lt;String&gt; 是个好主意?

 private Set<String> pkgs;

【讨论】:

  • 感谢您的回答,我会试一试并回复您
  • 谢谢@RexSplode,这就是问题所在。
【解决方案2】:

让我们考虑一下 ArrayList 的默认行为:

字符串数组列表有 5 个元素。如果您删除第 2 个位置的元素,则 arraylist 将变为 4 个元素的集合,第 3 个元素现在位于第 2 个位置。现在,当您删除第 5 个元素时,它的位置现在已更改。

所以使用hashmap的Arraylist,当你想从arraylist中移除元素时,你应该迭代arraylist的所有元素并从中移除特定元素。

或者,如果您只想在某些事件(如按钮按下)发生时检查项目,则仅从列表适配器获取检查项目。

【讨论】:

  • 感谢您的回答@S.K,我确实考虑过这个问题,但事实证明这是另一个问题,请参阅接受的答案
【解决方案3】:

问题在于您的情况。条件应该是这样的:

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

你可以参考链接:

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

How to Handle the checkbox ischecked and unchecked event in android

【讨论】:

  • 谢谢你的回答,逻辑上这两个条件是一样的,问题不是条件失败,是我使用的容器有问题,但是你的条件格式更好,我已经改变了我用你的。
猜你喜欢
  • 2011-06-01
  • 2012-10-16
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 2011-12-14
  • 2018-06-15
  • 2016-03-30
  • 2021-08-26
相关资源
最近更新 更多