2

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]]
5
  • Isnt making a new HashSet<Object>(List<Object> ... ) the answer? Then convert to List again Commented Mar 27, 2012 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? Commented Mar 27, 2012 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? Commented Mar 27, 2012 at 19:26
  • 1
    @Itfishie - [[1,2,3], [1,2], [3], [1,2]] to become become [[1,2,3], [1,2], [3]] Commented Mar 27, 2012 at 20:08
  • @Itfishie - sorry misunderstood i want it to become [1,2,3], your solution worked for me. Commented Mar 27, 2012 at 20:17

4 Answers 4

11

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);
}
Sign up to request clarification or add additional context in comments.

Comments

3
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]);
}
}

Comments

2

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);

Comments

0

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);
}

2 Comments

-1 for using iterator (instead of a for-each loop) and raw HashSet (which also doesn't preserve ordering of the original list)
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].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.