Modifying an ArrayList in Java

I want to search through an ArrayLst and delete any entries that are the same.

For example if my list was: apple, orange, banana, pear, peach, orange,

then "orange" would be deleted (both occurances).

Naively, I tried:

for(String word : userlist){

for(String otherword : userlist){

...
}
}

where I wrote how to .remove(lastIndexOf(userword)) if it equals word and their indexes are different.

This led to exception after exception, and I quickly realized I was manipulating a list while iterating through it which was making it all go wrong.

So decided to make a copy of the list

ArrayList<String> copylist = userlist;

for(String word : copylist){

    for(String otherword : copylist){

    if(word.equalsIgnoreCase(otherword) 
            && copylist.lastIndexOf(word)!=copylist.lastIndexOf(otherword)){

userlist.remove(userlist.lastIndexOf(word));
userlist.remove(userlist.lastIndexOf(otherword));
    }

    }
    }

SO I tried this, and it had similar problems. Notably ConcurrentModificationException. After tweaking it I can't get, what in my head should be a fairly easy process, to work in Java. Please help.

Answers


You're currently not making a copy of the list at all. You're declaring a new variable which has a reference to the same list. To make a copy of the list, use:

ArrayList<String> copyList = new ArrayList<String>(userList);

However, I'd suggest a different approach:

ArrayList<String> wordsToRemove = new ArrayList<String>();
Set<String> seenWords = new HashSet<String>();

for (String word : userList)
{
    if (!seenWords.add(word))
    {
        wordsToRemove.add(word);
    }
}

for (String word : wordsToRemove)
{
    // Keep removing it until it doesn't exist any more
    while (userList.remove(word)) {}
}

This doesn't ignore case, however. To do that, you need to be a bit smarter:

Set<String> wordsToRemove = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
Set<String> seenWords = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

for (String word : userList)
{
    if (!seenWords.add(word))
    {
        wordsToRemove.add(word);
    }
}

// Now we know the words we don't want, step through the list again and
// remove them (case-insensitively, as wordsToRemove is case-insensitive)
for (Iterator<String> iterator = userList.iterator(); it.hasNext() ;)
{
    if (wordsToRemove.contains(word))
    {
        iterator.remove();
    }
}

Need Your Help

Is use of the dependency injection pattern necessary to create professional code?

php javascript oop

I recently updated my PHP library to use the dependency injection pattern. Wrather than instantiating objects in my classes, I instantiate them in a class called ObjectMaker and pass the objects in

how to check if the record exists before insert to prevent duplicates?

sql sql-server sql-server-2008

I want to select CustomerID, OrderTypeID, and LoanNumber from tblOrder and insert it with a new OrderTypeID but same CustomerID and LoanNumber.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.