java - IndexOutOfBounds 异常将项目添加到 ArrayList
问题描述
为了显示图表,我有一个 asyncTask 读取大量产品列表,获取它们的类型并将它们添加到不同的子列表中。这是我的代码:
List<List<Bundle>> productsByType;
...
private class LoadDataForChart extends AsyncTask<Void, Float, Boolean> {
@Override
protected void onPreExecute() {
}
@Override
protected Boolean doInBackground(Void... params) {
productsByType = new ArrayList<>();
productsByType.add(new ArrayList<Bundle>());
productsByType.add(new ArrayList<Bundle>());
productsByType.add(new ArrayList<Bundle>());
productsByType.add(new ArrayList<Bundle>());
productsByType.add(new ArrayList<Bundle>());
List<Bundle> allProducts = dataManager.getAllProducts();
for(int i = 0; i < allProducts.size(); i++)
{
Bundle product = allProducts.get(i);
List<Bundle> productsByTypeSublist = null;
String productType = product.getString("type");
if(productType.equals("1"))
productsByTypeSublist = productsByType.get(0);
else if(productType.equals("2"))
productsByTypeSublist = productsByType.get(1);
else if(productType.equals("3"))
productsByTypeSublist = productsByType.get(2);
else if(productType.equals("4"))
productsByTypeSublist = productsByType.get(3);
else if(productType.equals("5"))
productsByTypeSublist = productsByType.get(4);
if(productsByTypeSublist != null)
productsByTypeSublist.add(product);
}
return true;
}
@Override
protected void onProgressUpdate(Float... values) {
}
@Override
protected void onPostExecute(Boolean result) {
showChartData();
}
@Override
protected void onCancelled() {
}
}
这是崩溃:
Caused by java.lang.ArrayIndexOutOfBoundsException: length=10; index=10
at java.util.ArrayList.add(ArrayList.java:468)
at com.mycompany.myapp.ui.fragments.ChartsFragment$LoadDataForChart.doInBackground(ChartsFragment.java:524)
at com.mycompany.myapp.ui.fragments.ChartsFragment$LoadDataForChart.doInBackground(ChartsFragment.java:415)
at android.os.AsyncTask$3.call(AsyncTask.java:378)
第 524 行是 productsByTypeSublist.add 行。有些崩溃是“length=10; index=10”,有些是“length=33; index=33”等等......我想这取决于allProducts有什么(?)。
我不明白的是为什么我在 List.add 方法中得到 ArrayIndexOutOfBoundsException ?特别是当我对该arrayList没有限制并且我添加没有索引的项目时,只是在列表的末尾?
我认为这可能是一个线程问题,即使它是 Crashlytics 日志的问题,而且问题确实出在我代码的其他点。
代码对我来说似乎很简单,我错过了什么?
解决方案
ArrayList
是不同步的,即当一个线程试图从中获取某些东西时,另一个线程可以修改它,反之亦然。
你试过用productsByType.add(Collections.synchronizedList(new ArrayList<Bundle>()))
吗?
在旁注中,您可以重写以下块
if(productType.equals("1"))
productsByTypeSublist = productsByType.get(0);
else if(productType.equals("2"))
productsByTypeSublist = productsByType.get(1);
else if(productType.equals("3"))
productsByTypeSublist = productsByType.get(2);
else if(productType.equals("4"))
productsByTypeSublist = productsByType.get(3);
else if(productType.equals("5"))
productsByTypeSublist = productsByType.get(4);
就像
productsByTypeSublist = productsByType.get(Integer.parseInt(productType) - 1);
推荐阅读
- python - Discord bot 不返回所有成员
- javascript - 如何从 react-native-maps 中获取折线的长度(公里)?
- javascript - 我可以检测用户何时通过直接链接或 react-router 进入我的网站吗?
- cookies - google colab 上的 RVL-CDIP 数据集
- prometheus - 如何从 2 个费率之和计算普罗米修斯百分比
- forge - 如何在外部系统中使用第三方 javascript 控件?
- android - Firebase Crashlytics SDK 更新不起作用。报告未显示在控制台中
- java - 在 java/spring 中为多个用例验证同一个 bean 的最佳方法是什么?
- javascript - 如何从javascript访问css类中定义的css变量?
- jquery - 使用 JavaScript 从 Laravel 的模态窗口对用户进行身份验证