Changing ArrayList in Java

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

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

then the "orange" will be deleted (both events).

Naively, I tried:

for(String word : userlist){ for(String otherword : userlist){ ... } } 

where I wrote as .remove (lastIndexOf (userword)) if it is equal to the word and their indices are different.

This led to an exception after the exception, and I quickly realized that I was manipulating the list, iterating through it, which made it all go wrong.

So, we 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. In particular, ConcurrentModificationException. After setting it up, I cannot get what in my head should be a fairly simple process to work in Java. Please, help.

+6
java arraylist
source share
7 answers

You are not currently making a copy of the list. You declare a new variable that references the same list. To make a copy of the list, use:

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

However, I would 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)) {} } 

However, this does not ignore the case. To do this, you need to be a little 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(); } } 
+10
source share
 import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class Test { public static void main(String[] args) { List<String> a = new ArrayList<String>(); a.add("apple"); a.add("orange"); a.add("banana"); a.add("pear"); a.add("peach"); a.add("orange"); System.out.println(a); System.out.println(getSingleWordList(a)); } private static List<String> getSingleWordList(List<String> list) { Set<String> uniques = new HashSet<String>(); Set<String> dups = new HashSet<String>(); for (String a : list) if (!uniques.add(a)) dups.add(a); uniques.removeAll(dups); return new ArrayList<String>(uniques); } } 

OUTPUT

Input = [apple, orange, banana, pear, peach, orange]

Output = [pear, apple, banana, peach]

+4
source share

If you want to delete an item during iteration through the collection, you should use Iterator and Iterator.remove ()

But I would like to offer you a simpler solution: put your list in a set. It automatically removes duplicates:

 List<String> mylist = new ArrayList<String>(); // some initialization: there are duplicates Set<String> myset = new HashSet<String>(mylist); // no duplicates here. 

You can continue to use set because it is a collection and you can iterate over it. But if you need random access, create the list again:

 newlist = new ArrayList<String>(myset); 

The order of the elements in the set will be "random" as a result of the hash. If you want to keep the original order, use LinkedHashSet instead of HashSet.

+2
source share
 ArrayList<String> copylist = userlist; 

This line assigns a reference list of users to copy and does not create a new arraylist. He points to the same arraist. To create a new list, an easy way is to create a new list and add items to this new list after checking if the item is in the new list or not.

 ArrayList<String> newList = new ArrayList<String> (); foreach(String item in userList) { if(newList.contains(item)==false) { newList.add(item); } } 
+1
source share

A well-known problem is that you cannot change the container that repeats. The trick to solve is to use the Iterator removal method:

  Iterator<String> tblIter = array.iterator(); while (tblIter.hasNext()) { String entry = tblIter.next(); if( entry.equals(.....) ) { ... tblIter.remove(); } } 
+1
source share

If you have control over adding data, you can create your own add method, for example:

 add(element) { if arrayList.contains(element) arrayList.remove(arrayList.indexOf(element)) else arrayList.add(element) } 

on the other hand, if you do not have control over how / when the data is added, you can make a loop and have the same logic in it, as indicated above. Look here for relevant methods.

0
source share

If the target is a collection without repeating elements, consider whether Set would be more appropriate than a list.

0
source share

All Articles