My code:
private Collection<Film> getFilms() {
File files = new File(pathname);
File[] filesList = files.listFiles();
List<Film> list = Arrays.asList();
Log.d("filesList.length ", ""+filesList.length);
for (int i = 0; i < filesList.length; i++) {
try {
Film filmTemp = new Film(filesList[i]);
list.set(i, filmTemp);
} catch (Throwable e) {
Log.d("Error!", "Kobzda", e);
}
}
return list;
}
And I always get the same errors:
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
java.lang.ArrayIndexOutOfBoundsException: length=0; index=1
You are calling Arrays.asList() with no params which means the list you are creating is immutable (cannot add or remove elements) and empty.
Even if the List was mutable (say, by doing List<Film> list = new ArrayList<>()) you'd still run into an issue because you can't call set on a non-existent element index. In other words, an element has to already exist at that index in the List in order to successfully call set.
Instead, you should create a mutable List and call add.
Something like:
private Collection<Film> getFilms() {
File files = new File(pathname);
File[] filesList = files.listFiles();
List<Film> list = new ArrayList<>();
Log.d("filesList.length ", ""+filesList.length);
for (int i = 0; i < filesList.length; i++) {
try {
Film filmTemp = new Film(filesList[i]);
list.add(filmTemp);
} catch (Throwable e) {
Log.d("Error!", "Kobzda", e);
}
}
return list;
}
If you take a look at the docs for List#set
Replaces the element at the specified position in this list with the specified element.
Throws: ...
IndexOutOfBoundsException - if the index is out of range (index < 0 || index >= size())
(Emphasis added.)
So this method doesn't add a new element at the given index, it replaces an element that must already be there. But when you instantiated the list using Arrays.asList(), you created an empty list. Since there's no element at index 0, you can't replace one there.
You should create the list using new ArrayList<>(), and then use List#add (Arrays.asList() returns a List that can't add elements to new indices; its size is fixed).
Related
I have two different lists, one is List<MainCategoriesAPI.Datum> datumList = new ArrayList<>(); and second is List<SubCategoryEnt> subCategoryEnts1 = new ArrayList<>();.
What I want is to compare these two lists and get those ids which are not present in datumList. And then, I want to delete the data regarding these ids from SubCategoryEnt.
If you are targeting above Android N
List<String> a1 = Arrays.asList("2009-05-18", "2009-05-19", "2009-05-21");
List<String> a2 = Arrays.asList("2009-05-18", "2009-05-18", "2009-05-19", "2009-05-19", "2009-05-20", "2009-05-21","2009-05-21", "2009-05-22");
List<String> result = a2.stream().filter(elem -> !a1.contains(elem)).collect(Collectors.toList());
or you can use the Collection interface's removeAll method.
// Create a couple ArrayList objects and populate them
// with some delicious fruits.
Collection firstList = new ArrayList() {{
add("apple");
add("orange");
}};
Collection secondList = new ArrayList() {{
add("apple");
add("orange");
add("banana");
add("strawberry");
}};
// Show the "before" lists
System.out.println("First List: " + firstList);
System.out.println("Second List: " + secondList);
// Remove all elements in firstList from secondList
secondList.removeAll(firstList);
// Show the "after" list
System.out.println("Result: " + secondList);
You have to use for loop to find the similar ids and the again use for loop to remove ids from datumList;
List<MainCategoriesAPI.Datum> datumList = new ArrayList<>();
List<SubCategoryEnt> subCategoryEnts1 = new ArrayList<>();
List<Integer> results = new ArrayList<Integer>();// this is for storing same ids
To get different ids
// to get same ids
if (datumList.size() == subCategoryEnts1.size()) {
for (int i=0; i<datumList.size();i++){
int datIds = datumList.get(i);
for (int j=0; j<subCategoryEnts1.size();j++){
int subId = subCategoryEnts1.get(j);
if (datIds!=subId){
results.add(subId);
break;
}
}
}
}
to remove ids
// to remove same id
for (int i=0; i<results.size();i++){
int datIds = results.get(i);
for (int j=0; j<datumList.size();j++){
int subId = datumList.get(j);
if (datIds==subId){
datumList.remove(j);
break;
}
}
}
Hope this will help you.
Check below to find missing items of subCategoryEnts1
List missingIds = new ArrayList<SubCategoryEnt>();
for (SubCategoryEnt subCategory : subCategoryEnts1) {
for (MainCategoriesAPI.Datum datam : datumList) {
if (datam.id == subCategory.id){
missingIds.add(subCategory);
break;
}
}
}
Now remove those from subCategoryEnts1
subCategoryEnts1.removeAll(missingIds);
I'm trying to get files from a folder and populate recyclerview based on the name of files using a custom adapter.
This is how I'm doing it:
In onBindViewHolder:
Product m = dataList.get(position);
//title
holder.title.setText(m.getTitle());
And :
void popList() {
Product product = new Product();
File dir = new File(mainFolder);//path of files
File[] filelist = dir.listFiles();
String[] nameOfFiles = new String[filelist.length];
for (int i = 0; i < nameOfFiles.length; i++) {
nameOfFiles[i] = filelist[i].getName();
product.setTitle(nameOfFiles[i]);
}
songList.add(product);
}
But the problem is, it just adds the first item.
I can't figure it out where should I loop to add it all.
You need to create separate product objects for items in loop and add it to list instead of creating a single Product object in list which will hold the last set data
void popList() {
Product product ;
File dir = new File(mainFolder);//path of files
File[] filelist = dir.listFiles();
String[] nameOfFiles = new String[filelist.length];
for (int i = 0; i < nameOfFiles.length; i++) {
// create product
product = new Product();
nameOfFiles[i] = filelist[i].getName();
product.setTitle(nameOfFiles[i]);
// add it to list
songList.add(product);
}
}
Your code walk through
void popList() {
Product product = new Product(); // one object
// ..code
for (int i = 0; i < nameOfFiles.length; i++) {
nameOfFiles[i] = filelist[i].getName();
product.setTitle(nameOfFiles[i]); // at the end of loop set last file name to object
}
songList.add(product); // one object in the list , end of story
}
I am developing an app in which i have a listview which contain some data from server and for this i am using json and also implemented adapter.notifyDataSetchanged() but i want to know whether i am doing in a write way or not pls check.
JSONArray posts = response.optJSONArray(ServerResponseStorage.s_szDEAL_ARRAY);// GETTING DEAL LIST
for (int i = 0; i < posts.length(); i++) {
try {
JSONObject post = posts.getJSONObject(i);// GETTING DEAL AT POSITION AT I
m_VcomData = new CVcomStorage();// object create of DealAppdatastorage
m_VcomData.setmDealTitle(post.getString(ServerResponseStorage.s_szDEAL_NAME));//getting deal name
m_VcomData.setmDealCode(post.getString(ServerResponseStorage.s_szDEAL_CODE));// getting deal code
m_VcomData.setmDealValue(post.getString(ServerResponseStorage.s_szDEAL_VAlUE));
m_VcomData.setmDescription(post.getString(ServerResponseStorage.s_szDEAL_DETAILS));
m_VcomData.setmDealActionUrl(post.getString(ServerResponseStorage.s_szDEAL_ACTION_URL));
String logo = post.getString(ServerResponseStorage.s_szDEAL_LOGO);
m_VcomData.setmIcon(imgPath + logo);
if (BuildConfig.klogInfo)
Log.d(m_kTAG, "Logo Path::" + item.getS_szicon());
if (BuildConfig.kMonkeyInfo)
Log.i("Monkey", "Logo Path::" + item.getS_szicon());
if (!s_VcomDataSet.contains(item)) {
s_VcomDataSet.add(m_VcomData);
m_VcomAdpter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);
First of all you need to write m_VcomAdpter.notifyDataSetChanged(); outside of the for loop because it will call again and again util your loops count.
2nd thing if you are creating or initalizing adapter after your api call then you don't need to call notifyDataSetChanged method.
So directly call this after for loop
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);
3rd thing if you modified your array then you can call like
m_VcomAdpter.notifyDataSetChanged()
e.g.
JSONArray posts = response.optJSONArray(ServerResponseStorage.s_szDEAL_ARRAY);// GETTING DEAL LIST
for (int i = 0; i < posts.length(); i++) {
try {
JSONObject post = posts.getJSONObject(i);// GETTING DEAL AT POSITION AT I
m_VcomData = new CVcomStorage();// object create of DealAppdatastorage
m_VcomData.setmDealTitle(post.getString(ServerResponseStorage.s_szDEAL_NAME));//getting deal name
m_VcomData.setmDealCode(post.getString(ServerResponseStorage.s_szDEAL_CODE));// getting deal code
m_VcomData.setmDealValue(post.getString(ServerResponseStorage.s_szDEAL_VAlUE));
m_VcomData.setmDescription(post.getString(ServerResponseStorage.s_szDEAL_DETAILS));
m_VcomData.setmDealActionUrl(post.getString(ServerResponseStorage.s_szDEAL_ACTION_URL));
String logo = post.getString(ServerResponseStorage.s_szDEAL_LOGO);
m_VcomData.setmIcon(imgPath + logo);
if (BuildConfig.klogInfo)
Log.d(m_kTAG, "Logo Path::" + item.getS_szicon());
if (BuildConfig.kMonkeyInfo)
Log.i("Monkey", "Logo Path::" + item.getS_szicon());
if (!s_VcomDataSet.contains(item)) {
s_VcomDataSet.add(m_VcomData);
}
} catch (Exception e) {
e.printStackTrace();
}
}
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);
notifyDatasetChanged() used for update the ListView item.
Suppose you have deleted or added something in your list in your case "s_VcomDataSet".
you should use notifyDatasetChanged() that reflects new changes in data and notifies ti listview.
For better usability you should use RecyclerView in place of listview
You should set the adapter before calling notifyDatasetChanged() on it. Your code should be along following lines-
CVcomStorage m_VcomData = new CVcomStorage();
m_VcomAdpter = new CVcomAdapter(HomeScreenActivity.this, s_VcomDataSet);
mVcomListview.setAdapter(m_VcomAdpter);
JSONArray posts = response.optJSONArray(ServerResponseStorage.s_szDEAL_ARRAY);// GETTING DEAL LIST
for (int i = 0; i < posts.length(); i++) {
try {
JSONObject post = posts.getJSONObject(i);// GETTING DEAL AT POSITION AT I
// object create of DealAppdatastorage
m_VcomData.setmDealTitle(post.getString(ServerResponseStorage.s_szDEAL_NAME));//getting deal name
m_VcomData.setmDealCode(post.getString(ServerResponseStorage.s_szDEAL_CODE));// getting deal code
m_VcomData.setmDealValue(post.getString(ServerResponseStorage.s_szDEAL_VAlUE));
m_VcomData.setmDescription(post.getString(ServerResponseStorage.s_szDEAL_DETAILS));
m_VcomData.setmDealActionUrl(post.getString(ServerResponseStorage.s_szDEAL_ACTION_URL));
String logo = post.getString(ServerResponseStorage.s_szDEAL_LOGO);
m_VcomData.setmIcon(imgPath + logo);
if (BuildConfig.klogInfo)
Log.d(m_kTAG, "Logo Path::" + item.getS_szicon());
if (BuildConfig.kMonkeyInfo)
Log.i("Monkey", "Logo Path::" + item.getS_szicon());
if (!s_VcomDataSet.contains(item)) {
s_VcomDataSet.add(m_VcomData);
m_VcomAdpter.notifyDataSetChanged();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I'm iterating through a cursor and populating a SparseArray with ArrayList's containing bundles of information from the cursor:
// An ArrayList to hold all of our components per section
ArrayList<ObjectKanjiLookupChar> al = new ArrayList<ObjectKanjiLookupChar>();
// We'll hold on to all of the above ArrayLists and process them at once
SparseArray<ArrayList<ObjectKanjiLookupChar>> compArray = new SparseArray<ArrayList<ObjectKanjiLookupChar>>();
do
{
// Read values from the cursor
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String component = cursor.getString(cursor.getColumnIndex("component"));
int compStrokes = cursor.getInt(cursor.getColumnIndex("strokes"));
// Create a new object for this component so we can display it in the GridView via an adapter
ObjectKanjiLookupChar oklc = new ObjectKanjiLookupChar();
oklc.setCharacterID(id);
oklc.setCharacter(component);
oklc.setStrokeCount(compStrokes);
al.add(oklc);
// Add headers whenever we change stroke groups
if(compStrokes != strokesSection)
{
compArray.put(strokesSection, al);
al.clear();
strokesSection = compStrokes;
}
}
while(cursor.moveToNext());
// Add the final group of components to the array
compArray.put(strokesSection, al);
Immediately afterwards, I iterate through the SparseArray:
for(int i = 0; i < compArray.size(); i++)
{
Integer strokes = compArray.keyAt(i);
ArrayList<ObjectKanjiLookupChar> alComp = compArray.get(strokes);
// DEBUG
Log.i("DialogKanjiLookup", "Components in Section " + strokes + ": " + alComp.size());
ll.addView(createNewSection(String.valueOf(strokes), alComp));
}
For some unknown reason, the Log() call above reports that alComp has zero entries. I verified that ArrayList.size() was returning numbers greater than 0 when I put() them into the SparseArray, so I must be doing something incorrect when iterating through the SparseArray. What is going on?
I suspect that the problem comes from this piece of code:
if(compStrokes != strokesSection)
{
compArray.put(strokesSection, al);
al.clear(); // Here
strokesSection = compStrokes;
}
You cleared the array list after you added to the SparseArray. You might think that after you have added the list to the SparseArray, SparseArray would keep a copy of the ArrayList. However, they actually share the same reference. Since you cleared the ArrayList, you cleared out the one inside SparseArray too.
The following code should fix the problem.
// We'll hold on to all of the above ArrayLists and process them at once
SparseArray<ArrayList<ObjectKanjiLookupChar>> compArray = new SparseArray<ArrayList<ObjectKanjiLookupChar>>();
do
{
// Read values from the cursor
int id = cursor.getInt(cursor.getColumnIndex("_id"));
String component = cursor.getString(cursor.getColumnIndex("component"));
int compStrokes = cursor.getInt(cursor.getColumnIndex("strokes"));
// Create a new object for this component so we can display it in the GridView via an adapter
ObjectKanjiLookupChar oklc = new ObjectKanjiLookupChar();
oklc.setCharacterID(id);
oklc.setCharacter(component);
oklc.setStrokeCount(compStrokes);
ArrayList<ObjectKanjiLookupChar> al = compArray.get(comStrokes);
if(al == null) {
al = new ArrayList<ObjectKanjiLookupChar>();
compArray.put(comStrokes, al);
}
al.add(oklc);
}
while(cursor.moveToNext());
Can anybody tell me where I am going wrong here?
File promoCountFile = new File(RaconTours.PATH + "promocodeCount.txt");
if (promoPlistPath.exists()) {
try {
ObjectInputStream inStream = new ObjectInputStream(new FileInputStream(promoPlistPath));
ObjectInputStream promoStream = new ObjectInputStream(new FileInputStream(promoCountFile));
promoobj = (ArrayList<HashMap<String, Object>>) promoStream.readObject();
obj = (ArrayList<HashMap<String, Object>>) inStream.readObject();
for (HashMap<String, Object> tmpObj : obj) {
promoTourname = (String) tmpObj.get("promoTour");
promocodeID = (String) tmpObj.get("promocode");
if (promoTourname.equals(currentTour.getObjtourName())) {
//if the condition is met, remove the entry from the file
for (HashMap<String, Object> promoTemp : promoobj) {
promoTourCount = (Integer) promoTemp.get("promocodeTourCount");
}
obj.remove(tmpObj);
--promoTourCount;
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(promoPlistPath));
out.writeObject(obj);
out.close();
ObjectOutputStream promoout = new ObjectOutputStream(new FileOutputStream(promoCountFile));
HashMap<String, Object> promoCountDict = new HashMap<String, Object>();
promoobj.remove(0);
promoCountDict.put("promocodeTourCount",promoTourCount);
promoobj.add(promoCountDict);
promoout.writeObject(promoobj);
promoout.close();
}
}
if (obj.size() == 0 || promoTourCount == 0) {
promoPlistPath.delete();
promoCountFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Here it is giving me concurrent modification exception while the for loop iterates for the 2nd time or after that.
I am trying to update the value of promoTourCount in file each time as the loop iterates. But I am failing to do it. Because to avoid adding up multiple objects I am removing the object present at position 0 and adding the new one to that position( promoobj.remove(0);)
Plz help me
You are modifying the collection you are iterating on. This will trigger an error. You iterate over obj here:
for (HashMap<String, Object> tmpObj : obj) {
But remove from it here:
obj.remove(tmpObj);
I recommend you to store the items to remove in another collection and remove them from the map only when you finish the for loop.
Edit: << Adding example code >>
List<Integer> toRemove = new LinkedList<Integer>();
for (int i = 0; i < obj.size(); i++) {
HashMap<String, Object> tmpObj = obj.get(i);
if (/* something */) {
/* ... */
/* obj.remove(tmpObj); replaced with*/
toRemove.add(0, i); // notice that I add bigger indices first
}
}
// Here we make the removal from bigger indices to smaller ones
// Notice that we iterate and remove from different collections.
for (Integer indexToDelete : toRemove) {
obj.remove(indexToDelete);
}
This is the basic idea when you want to remove elements. However you need to output obj as modified immediately in the for loop. Then probably a bit of hacks with the indices will do better job for you:
for (int i = 0; i < obj.size(); i++) {
HashMap<String, Object> tmpObj = obj.get(i);
if (/* something */) {
/* ... */
/* obj.remove(tmpObj); replaced with*/
obj.remove(i); // We erase the element but this time we do not use enhanced for loop which is ok.
i--; // we decrease the index because th enumber of elements decreased. Index hack. Ugly.
System.out.println(obj); // modified obj :)
}
}