Why is arraylist loop crashing on removing elements - java

I'm trying to print all the elements of an arraylist and remove them from the array at the same time using the following code.
while(!duplicates.isEmpty()){
outpurWriter.println(duplicates.remove(0));
}
It works when the arraylist is small in size but if the arraylist contains say 400000 elements it crashes after the first few thousand.
I've changed my code around to just use a for loop to print each element then set the arraylist = null, but just wondering what is wrong with the code I used originally.
Cheers

Try this,
public static void main(String[] args)
{
List<String> listString = new ArrayList<String>();
listString.add("a");
listString.add("b");
listString.add("c");
listString.add("d");
System.out.println("Size of arraylist before remove: "+listString.size());
ListIterator<String> listIterator = listString.listIterator();
while (listIterator.hasNext())
{
listIterator.next();
listIterator.remove();
}
System.out.println("Size of arraylist after remove: "+listString.size());
}
If you have requirement where you have more insert and delete operations, please use linkedlist

Related

How to populate an ArrayList<ArrayList<String>> that contains another ArrayList<String>

I was trying to populate an arraylist to contain another arraylist but after the loop finishes adding the sub arraylist to the parent in the first round, in the next round it overwrites the previously added row and duplicates the value of 2nd round and so on; so finally i get an arraylist having duplicate rows all of them having values the last row in the cursor. To clarify it well... instead of returning something like this
[Quote1, Location1]
[Quote2, Location2]
[Quote3, Location3]
[Quote4, Location4]
it returns something like
[Quote4, Location4]
[Quote4, Location4]
[Quote4, Location4]
[Quote4, Location4]
Here is my code:
public ArrayList<ArrayList<String>> getAllVerses() {
ArrayList<ArrayList<String>> allVersesAL = new ArrayList<ArrayList<String>>();
ArrayList<String> subAL = new ArrayList<>();
Cursor allVerse = getAllQuote(); //It's an outsider method
allVerse.moveToFirst();
do {
//subAL.clear();
subAL.add(allVerse.getString(allVerse.getColumnIndex(VERSE)));
subAL.add(allVerse.getString(allVerse.getColumnIndex(LOC_AUTH)));
Log.d("Content of subAL", subAL + "");
allVersesAL.add(subAL);
} while (allVerse.moveToNext());
for (List<String> li : allVersesAL) {
for (String s : li) {
Log.d("getAllVerses", "Inside the second for loop...");
Log.d("Testing arraylist...", s + " : ");
}
}
return allVersesAL;
}
It assigns the data to the sub ArrayList from a cursor object. Please help!!! I spent a lot of time on this but couldn't figure out what's wrong with my code. Bless you all!
When you insert a object in a List the actual object is inserted into the list. It isn't copied. If you do further operations on the same object it will affect the object stored in the list.
What you need to do is to create a new ArrayList object for each iteration of the outer loop of your population code.
do {
//subAL.clear();
subAl = new ArrayList<String>();
Move ArrayList<String> subAL = new ArrayList<>(); inside the do while loop

ArrayList method "lastIndexOf" returning -1 when item does exist in ArrayList

I'm trying to get the basics of ArrayLists, but I can't get the lastIndexOf method to work properly. As you can see in my code below, the program runs and should print "1", the index of the number 3, but prints "-1" instead (which should be printed only if 3 didn't exist in the ArrayList). What's my problem?
import java.util.ArrayList;
public class Pile {
public static void main(String[] args)
{
int[] myArray = {1,3,23,4};
ArrayList<Integer> myList = new ArrayList<Integer>();
for (int i=0;i<myArray.length;i++) {
myList.add(myArray[0]);
}
System.out.println(myList.lastIndexOf(3));
}
}
You're only adding the first element of myArray to myList
You should replace
myList.add(myArray[0]);
with this
myList.add(myArray[i]);
Also, instead of manually copying the elements, you could use Arrays#asList (but you would need to change the type of myArray to Integer[]):
List<Integer> myList = Arrays.asList(myArray);
You are only adding the first element of the array multiple times to the list.
myList.add(myArray[0]);
That's why your list doesn't contain 3.
Change it to
myList.add(myArray[i]);

Best way to Iterate collection classes?

Guys i wanna ask about the best way to iterate collection classes ??
private ArrayList<String> no = new ArrayList<String>();
private ArrayList<String> code = new ArrayList<String>();
private ArrayList<String> name = new ArrayList<String>();
private ArrayList<String> colour = new ArrayList<String>();
private ArrayList<String> size = new ArrayList<String>();
// method for finding specific value inside ArrayList, if match then delete that element
void deleteSomeRows(Collection<String> column, String valueToDelete) {
Iterator <String> iterator = column.iterator();
do{
if (iterator.next()==valueToDelete){
iterator.remove();
}
}while(iterator.hasNext());
}
deleteSomeRows(no, "value" );
deleteSomeRows(code, "value" );
deleteSomeRows(name , "value");
deleteSomeRows(colour ,"value" );
deleteSomeRows(size , "value");
THE PROBLEM WITH CODES ABOVE IS THAT IT TAKES AMOUNT OF TIME JUST TO ITERATE EACH OF THOSE CLASSES ? ANY SOLUTION TO MAKE IT FASTER ? pls help if u care :D..
You could simplify your code:
while column.contains(valueToDelete)
{
column.remove(valueToDelete);
}
You're not going to be able to speed up your ArrayList iteration, especially if your list is not sorted. You're stuck at O(n) for this problem. If you sorted it and inserted logic to binary search for the item to remove until it is no longer found, you could speed up access.
This next suggestion isn't directly related to the time it takes, but it will cause you problems.
You should never compare String objects for equality using the == operator. This will cause a comparison of their pointer values.
Use this instead:
if (iterator.next().equals(valueToDelete))
EDIT: The problem here is not the iteration. The problem is removing the elements from the ArrayList. When you remove the first element from an ArrayList, then all subsequent elements have to be shifted one position to the left. So in the worst case, your current approach will have quadratic complexity.
It's difficult to avoid this in general. But in this case, the best tradeoff between simplicity and performance can probably be achieved like this: Instead of removing the elements from the original list, you create a new list which only contains the elements that are not equal to the "valueToDelete".
This could, for example, look like this:
import java.util.ArrayList;
import java.util.List;
public class QuickListRemove
{
public static void main(String[] args)
{
List<String> size = new ArrayList<String>();
size = deleteAll(size, "value");
}
private static <T> List<T> deleteAll(List<T> list, T valueToDelete)
{
List<T> result = new ArrayList<T>(list.size());
for (T value : list)
{
if (!value.equals(valueToDelete))
{
result.add(value);
}
}
return result;
}
}
If you want to modify the collection while iterating them then you should use Iterators, otherwise you can use the for-each loop.
For -each :
// T is the type f elements stored in myList
for(T val : myList)
{
// do something
}
Try putting a break after you find the element to delete.

ArrayList index out of bounds exception

Recently while using arrayList I found a weird issue. I want to keep 2 elements in the arraylist and would like to keep object1 in element 0 and object2 in element1.
I am deciding this in a loop.
When it happens to add the first element its throwing indexOutofBounds. As per java doc as the index is greater than size its doing this.
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add(1,"SECONDITEM"); // throwing due to size is not set
list.add(0,"FIRSTITEM");
int postn=0;
for(String item:list){
System.out.println("Position "+postn+" :"+item);
postn++;
}
}
Then I tried to setup other items as placeholder in 0,1 element and tried to do same
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add(0,"x");
list.add(1,"y");
list.add(1,"SECONDITEM");
list.add(0,"FIRSTITEM");
int postn=0;
for(String item:list){
System.out.println("Position "+postn+" :"+item);
postn++;
}
}
Output:
Position 0 :FIRSTITEM
Position 1 :x
Position 2 :SECONDITEM
Position 3 :y
How to get over this issue. One way I found is to remove the element in the index and add the element. Is there a better option.
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add(0,"x");
list.add(1,"y");
list.remove(1);
list.add(1,"SECONDITEM");
list.remove(0);
list.add(0,"FIRSTITEM");
int postn=0;
for(String item:list){
System.out.println("Position "+postn+" :"+item);
postn++;
}
}
Position 0 :FIRSTITEM
Position 1 :SECONDITEM
.add() method insert the element at the given position and shift the other element accordingly
to overwrite the value at particular index you have to use the .set(position, value)
try the set method ..
list.add(0,"x");
list.add(1,"y");
list.set(1,"SECONDITEM");
list.set(0,"FIRSTITEM");
now it will return the only two values.
When you call in this order:
ArrayList<String> list = new ArrayList<String>();
list.add(1,"SECONDITEM"); // throwing due to size is not set
You are trying to add to position "1", but nothing has been added to the list yet. I believe that is why you get the error. Instead you probably want to use just:
ArrayList<String> list = new ArrayList<String>();
list.add("FIRSTITEM");
Since it's an empty list. You can also use the index, but you'll have to increment each time. Makes sense?
The issue is ... you're trying to use a List in a way it wasn't intended to be used. As you've found out, you can't set or add to an index that is outside the range of the current size.
If you know in advance the size you need and it's a fixed size, using a String[] is the better choice.
If you really want/need a dynamic structure that allows random access sets regardless of the current size, write your own method to fill the list when needed:
public static <T> void fillAndSet(int index, T object, List<T> list)
{
if (index > (list.size() - 1))
{
for (int i = list.size(); i < index; i++)
{
list.add(null);
}
list.add(object);
}
else
{
list.set(index, object);
}
}

How to change every string element of an arraylist?

I have a ListView with an arraylist with an unknown number of string elements. I want to change/modify every single one of these string items. The problem is that i dont know how many items there are since the user can change it.
I have a translate function that takes a string and returns a string. What i want to do is
arraylistelement1 = translate(arraylistelement1);
arraylistelement2 = translate(arraylistelement2);
...
and repopulate the listview arraylist with the new strings.
Whats a way to do this?
Iterate over the list and create a new list of translated options from the original then replace the contents of the original list with the new values. If you do the replacing while iterating you'll get ConcurrentModificationExceptions.
Use ListIterator.set:
public static void main(String[] args) {
List<String> list = new ArrayList<>(Arrays.asList("s0", "s1", "s2"));
ListIterator<String> iter = list.listIterator();
while (iter.hasNext())
iter.set(translate(iter.next()));
for (String element : list)
System.out.println(element);
}
public static String translate(String element) {
return element + " " + Math.random();
}

Categories

Resources