【问题标题】:Fatal exception while removing duplicate strings from a list从列表中删除重复字符串时出现致命异常
【发布时间】:2020-05-18 11:23:31
【问题描述】:

基本上,我的应用程序的一个函数应该从 Firestore 获取一个包含不同字符串的数组。然后另一个函数应该从该数组中选择 3 个不同的字符串并将其存储在一个列表中。字符串不应该是相同的,所以最后这个列表应该有 3 个来自我从 Firestore 获得的数组中的唯一随机字符串。

为了实现这一点,我有下面的代码(不幸的是我不是自己写的)。大多数情况下,这段代码运行良好,但有时我没有得到任何价值。因此,正如我所说,有时我会收到此错误,这将我指向removeDuplicatesmethod:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.guessit, PID: 30272
    java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
        at java.util.ArrayList.get(ArrayList.java:437)
        at com.example.android.guessit.GameFlow.SecondRound.FragmentCategory_2.removeDuplicates(FragmentCategory_2.java:767)
        at com.example.android.guessit.GameFlow.SecondRound.FragmentCategory_2.access$100(FragmentCategory_2.java:49)
        at com.example.android.guessit.GameFlow.SecondRound.FragmentCategory_2$1.onComplete(FragmentCategory_2.java:99)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7050)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

这是我使用我解释的功能的片段。所以基本上getRandomElementfunction 从我从数据库中获得的数组中获取一个随机字符串并将其放入一个列表中,但在此之前removeDuplicatesfunction 检查该字符串是否已经在列表中并相应地删除它:

 @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

...

        btnNavFragCat1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                questionKeyRef.document(mTvCat1).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                        if (task.isSuccessful()) {

                            DocumentSnapshot document = task.getResult();
                            List<String> questions = (List<String>) document.get("questions");

                            List<String> randomList = getRandomElement(questions, 6);

                            removeDuplicates(randomList);

                            viewModel.setCategory(mTvCat1);

                            category.put("category", mTvCat1);
                            setUpCategory();

                            setUpQuestions();
                        }
                    }
                });

            }
        });

...

    private void removeDuplicates(List<String> list) {
        int count = list.size();
        for (int i = 0; i < count; i++) {
            for (int j = i + 1; j < count; j++) {
                if (list.get(i).equals(list.get(j))) {
                    list.remove(j--);
                    count--;
                }
            }
        }

        query1 = list.get(0);
        query2 = list.get(1);
        query3 = list.get(2);

        Log.d("One", list.get(0));
        Log.d("Two", list.get(1));
        Log.d("Three", list.get(2));
    }

    private List<String> getRandomElement(List<String> list, int totalItems) {
        Random rand = new Random();
        List<String> newList = new ArrayList<>();
        for (int i = 0; i < totalItems; i++) {
            int randomIndex = rand.nextInt(list.size());
            newList.add(list.get(randomIndex));
        }
        return newList;
    }

...

我非常感谢任何帮助,并希望有人可以向我解释错误并可能给我一个解决方案。

【问题讨论】:

  • 我有一个问题:如果getRandomElementquestions List 返回一个值,为什么randomList 是一个字符串列表?
  • 这里的堆栈跟踪非常简单,java.lang.IndexOutOfBoundsException: Index: 2, Size: 2 -> 在删除重复项中调用 get 函数时,您的元素少于预期 -> 要么调试代码, 或在将对象分配给查询之前将日志记录样式更改为日志 [123] 并记录您拥有的整个列表,而不是在记录器中使用 get 函数。
  • @LucaMurra 我其实不知道,因为那不是我写的代码。
  • @LucaMurra 它已经在我的帖子中了

标签: java android arraylist random


【解决方案1】:

你应该在你的RemoveDuplicates中加入一些避免IndexOutOfBoundException的东西:

private void removeDuplicates(List<String> list) {
    int count = list.size();
    for (int i = 0; i < count; i++) {
        for (int j = i + 1; j < count; j++) {
            if (list.get(i).equals(list.get(j))) {
                list.remove(j--);
                count--;
            }
        }
    }

    query1 = list.get(0);
    query2 = list.get(1);    //This
    query3 = list.get(2);    //And this, could be out of bound, for example if the list is something like {"a","a","a","a"}, so without duplicates it becomes {"a"}

    Log.d("One", list.get(0));
    Log.d("Two", list.get(1));
    Log.d("Three", list.get(2));
}

所以我建议改变它:

private void removeDuplicates(List<String> list) {
        int count = list.size();
        for (int i = 0; i < count; i++) {
            for (int j = i + 1; j < count; j++) {
                if (list.get(i).equals(list.get(j))) {
                    list.remove(j--);
                    count--;
                }
            }
        }
        count = list.size();

        if (count >= 3) {
            query1 = list.get(0);
            query2 = list.get(1);
            query3 = list.get(2);
        }
        else if (count >= 2) {
            query1 = list.get(0);
            query2 = list.get(1);
            query3 = "";
        }
        else if (count >= 1) {
            query1 = list.get(0);
            query2 = "";
            query3 = "";
        }
        else {
            query1 = "";
            query2 = "";
            query3 = "";
        }



        Log.d("One", query1);
        Log.d("Two", query2);
        Log.d("Three", query3);
    }

【讨论】:

    猜你喜欢
    • 2014-08-02
    • 2011-12-17
    • 2019-05-05
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多