0

I have an ArrayList which is getting populated with string array. At the end of the process I have to remove the duplicates string arrays added to the list. I tried doing the conventional solution of using LinkedHashSet and populating into a new Array List, but in vein.

List<String[]> OrgList = new ArrayList<String[]>();
//String arrays added to OrgList 
.....
.....
List<String[]> NewList = new ArrayList<String[]>(new LinkedHashSet<String[]>(OrgList));

Is there any other way to remove duplicates in this scenario?

Thanks in Advance.

  • Why are you using String array then why not set directly? – SMA Jan 06 '15 at 12:45
  • @almasshaikh look here why set wont work here : http://stackoverflow.com/questions/10154305/java-checking-equality-of-arrays-order-doesnt-matter – Suresh Atta Jan 06 '15 at 12:47
  • Unless i got it wrong and If i understand OP's question then adding set instead of array wont help him @sᴜʀᴇsʜᴀᴛᴛᴀ? – SMA Jan 06 '15 at 12:50

6 Answers6

0

LinkedHashSet did not work, because it's String arrays, that you are adding, for which equals is taken from Object.

  1. If order does not matter, you can use TreeSet with custom Comparator, although you will loose order.

  2. If you can switch from arrays of Strings to List, your LinkedHashSet would work

mavarazy
  • 7,562
  • 1
  • 34
  • 60
0

This should work

    TreeSet<String[]> set = new TreeSet<String[]>(new Comparator<String[]>() {
        @Override
        public int compare(String[] o1, String[] o2) {
            return Arrays.equals(o1, o2) ? 0 : 1;
        }});
    set.addAll(list);
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
0

You can use this code

private String getArrayKey(String[] list) {
        StringBuffer temp = new StringBuffer();
        for (String s : list) {
            temp.append(s).append("-");
        }
        return temp.toString();
    }

Then put your List in a Map in this way.

Map<String , String []> map = new HashMap<String, String[]>();
        for (String[] strings : OrgList ) {
            map.put(getArrayKey(strings), strings);            
        }

and finally retrive your list

List<String[]> NewList = new ArrayList<String[]>();
NewList.addAll(map.values());
mehdinf
  • 59
  • 4
0

Same TreeSet can be used only the comparison need to be changed as Arrays.equal doesn't support String[].

TreeSet<String[]> set = new TreeSet<String[]>(new Comparator<String[]>() {
            @Override
            public int compare(String[] o1, String[] o2) {
                return Arrays.asList(o1).containsAll(Arrays.asList(o2))?0:1;
            }});
        set.addAll(origList);
Nagappan
  • 346
  • 2
  • 8
0

TreeSet(Ordering)

String[] array = new TreeSet<String>(Arrays.asList(str)).toArray(new String[0]);

or HashSet(Faster,No ordering)

String[] array = new HashSet<String>(Arrays.asList(str)).toArray(new String[0]);
saneryee
  • 3,239
  • 31
  • 22
0

Unfortunately, there's no distinctBy in Java 8 Stream API, but what you want is still possible with streams in this situation by just using Arrays.asList(array):

List<String[]> list = new ArrayList<String[]>();

//...

List<String[]> result = 
    list.stream()
        .map(s -> Arrays.asList(s))
        .distinct()
        .collect(Collectors.toList());

Reason why it works is that List implementations should implement equals comparing the contents, thus Stream.distinct() will work with lists.

Arrays.asList(array) doesn't copy the arrray but creates view on the array and therefore causes not much overhead.

hotkey
  • 140,743
  • 39
  • 371
  • 326