Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an ArrayList that has a nested ArrayList of Strings and I want to remove duplicates from. I know if I always wanted to remove duplicates, I shouldn't use an ArrayList, but in some cases duplicates are valid. What is the best way to remove duplicates from the nested ArrayList?

For example, I would like to execute some Java that converts:

[[duplicate], [duplicate], [duplicate], [unique1], [unique2]]

to:

[[duplicate], [unique1], [unique2]]
share|improve this question
    
Isnt making a new HashSet<Object>(List<Object> ... ) the answer? Then convert to List again –  kamil Mar 27 '12 at 19:17
    
You say that it's a list of lists. Do you want { {1, 2}, {1, 3} } to be collapsed to { { 1, 2 }, { 3 } }? or should each inner list be treated in isolation? –  aioobe Mar 27 '12 at 19:20
2  
I am a bit confused too. Are you looking for [[1,2,3], [1,2], [3], [1,2]] to become [[1,2,3], [1,2], [3]], or [1, 2, 3] or what aioobe said? –  ltfishie Mar 27 '12 at 19:26
1  
@Itfishie - [[1,2,3], [1,2], [3], [1,2]] to become become [[1,2,3], [1,2], [3]] –  c12 Mar 27 '12 at 20:08
    
@Itfishie - sorry misunderstood i want it to become [1,2,3], your solution worked for me. –  c12 Mar 27 '12 at 20:17

4 Answers 4

up vote 2 down vote accepted

What aioobe said, using a set, except you will put it in a loop since you have a two demisional array:

Set<String> set = new LinkedHashSet<String>();
for (ArrayList<String> list:yourList) {
    set.addAll (list);
}
ArrayList<String> uniqueList = new ArrayList<String>(set);
share|improve this answer

To remove duplicates from an ArrayList you could do

yourList = new ArrayList<String>(new LinkedHashSet<String>(yourList));

Using LinkedHashSet instead of a HashSet ensures that the order of the original lists are preserved.


Regarding your comment:

Here's a solution that transforms [[1,2,3], [1,2], [3], [1,2]] to [[1,2,3], [1,2], [3]].

Set<String> seen = new HashSet<String>();
for (List<String> l : strLists) {
    for (Iterator<String> iter = l.iterator(); iter.hasNext(); )
        if (!seen.add(iter.next()))
            iter.remove();

    // If you want to remove lists that end up empty:
    if (l.isEmpty())
        strLists.remove(l);
}
share|improve this answer
import java.util.Arrays;

public class RunDuplicate
{
public RunDuplicate()
{
super();
}

public static void main(String[] args)
{
String[] duplicates = new String[] {"duplicate","duplicate","duplicate","unique1","unique2"};

Arrays.sort(duplicates);

int k = 0;

for (int i = 0; i < duplicates.length; i++)
{
if (i > 0 && duplicates[i].equals(duplicates[i -1]))
continue;

duplicates[k++] = duplicates[i];
}

String[] unique = new String[k];

System.arraycopy(duplicates, 0, unique, 0, k);

//test that unique contains no duplicate strings
for (int i = 0; i < unique.length; i++)
System.out.println(unique[i]);
}
}
share|improve this answer

You can do that like this:

for (Iterator<ArrayList<String>> it = myListInList.iterator(); it.hasNext();)
{ 
   ArrayList<String> current = it.next();
   HashSet h = new HashSet(current);
   current.clear();
   current.addAll(h);
}

share|improve this answer
    
+1 for using iterators –  ltfishie Mar 27 '12 at 19:21
    
Why not use a for-each loop? –  aioobe Mar 27 '12 at 19:25
1  
-1 for using iterator (instead of a for-each loop) and raw HashSet (which also doesn't preserve ordering of the original list) –  Natix Mar 27 '12 at 19:43
    
I think using iterator pattern is useful. Hashset will cause that the ordering will be corrupt but it was irrelevant in this case [i can't see it as prerequisite]. –  dexametason Mar 27 '12 at 19:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.