573

I have an ArrayList<String>, and I want to remove repeated strings from it. How can I do this?

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
user25778
  • 5,901
  • 3
  • 20
  • 12

40 Answers40

1094

If you don't want duplicates in a Collection, you should consider why you're using a Collection that allows duplicates. The easiest way to remove repeated elements is to add the contents to a Set (which will not allow duplicates) and then add the Set back to the ArrayList:

Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);

Of course, this destroys the ordering of the elements in the ArrayList.

Ivar
  • 6,138
  • 12
  • 49
  • 61
jonathan-stafford
  • 11,647
  • 1
  • 17
  • 11
  • 291
    See also LinkedHashSet, if you wish to retain the order. – volley Dec 09 '09 at 20:38
  • But this will just create the set without duplicates , I want to know which number was duplicate in O(n) time – Chetan Mar 29 '12 at 19:43
  • Chetan, finding the items in O(n) is possible if the set of possible values is small (think Byte or Short); a BitSet or similar can then be used to store and look up already encountered values in O(1) time. But then again - with such a small value set, doing it in O(n log n) might not be a problem anyway since n is low. (This comment is not applicable to original poster, who needs to do this with String.) – volley May 03 '12 at 12:38
  • 3
    @Chetan finding all duplicates from ArrayList in O(n), its important to have correctly defined equals method on objects which you have in the list (no problem for numbers): `public Set findDuplicates(List list) { Set items = new HashSet(); Set duplicates = new HashSet(); for (Object item : list) { if (items.contains(item)) { duplicates.add(item); } else { items.add(item); } } return duplicates; }` – Ondrej Bozek Jun 20 '12 at 12:06
  • this is great, and it gets even better if you change HashSet to LinkedHashSet – Kevik Jul 23 '13 at 11:07
  • 6
    A good practice would be to define variables using the interface types `List` and `Set` (instead of implementation types `ArrayList` and `HashSet` as in your example). – Jonik Aug 29 '13 at 07:27
  • 35
    You can clean this up by using `new HashSet(al)` instead of initializing it to empty and calling `addAll`. – ashes999 Dec 26 '13 at 12:44
  • 1
    can I add rules for setting what's duplicate to me? For example: when my `Object` has several values if two of them repeat I consider them as duplicate (other values can be different) and use `Set`? – jean d'arme Aug 18 '15 at 09:32
  • @jonathan-stafford nice and useful peace of code. voteup – Maytham Fahmi Nov 14 '15 at 12:25
  • One reason that I am force to use collection instead of set is due to HTTP API calls. The API returns a POJO of certain objects, I need to act data on it so I really need it not to be duplicated. For some reason, it wasn't part of the API, to return to me a list of non-duplicated data, I cannot wait until it is developed so I must find a way to present a list with no duplicates. – Neon Warge Aug 03 '16 at 07:45
  • And the OneLiner would be: `myArrayList = new ArrayList(new HashSet(myArrayList));` (But just do it if you really need the ArrayList before AND after this line!) – r00tandy Aug 27 '16 at 11:25
  • 2
    @jeand'arme If you use a TreeSet instead of a HashSet, you can define your own Comparator to use, and the TreeSet will consider two items to be duplicates if the Comparators .compare(e1, e2) returns 0. Note that this will destroy the existing order of the arraylist. – Jarred Allen Aug 27 '16 at 21:48
  • what is the time complexity ? – Giacomo Nov 14 '18 at 15:52
  • 1
    not working with ArrayList having model instead of string . – Ajay Mistry Feb 26 '20 at 12:16
  • 2
    Alternative: `Set set = new HashSet<>(); yourList.removeIf(x -> !set.add(x));` The advantage is that this alternative allows you to decide what to use in the `set.add(…)` expression, for your particular notion of “duplicate”. It’s also independent of the list’s actual elements type. It also retains the order, regardless of whether the set maintains the order or not. Also usable with a `TreeSet` (e.g. with custom comparator) instead of `HashSet`. – Holger Jun 04 '20 at 07:42
  • For those, who have problem in understanding ArrayList arrList3 = new ArrayList(Arrays.asList(1, 23, 1, 3, 3, 2, 3, 2, 12, 67, 23, 12, 34, 9)); Collection set = new HashSet<>(arrList3); arrList3.clear(); arrList3.addAll(set); System.out.println(set); – Jwala Kumar Apr 10 '22 at 05:30
318

Although converting the ArrayList to a HashSet effectively removes duplicates, if you need to preserve insertion order, I'd rather suggest you to use this variant

// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);

Then, if you need to get back a List reference, you can use again the conversion constructor.

IgorGanapolsky
  • 26,189
  • 23
  • 116
  • 147
abahgat
  • 13,360
  • 9
  • 35
  • 42
  • 12
    Does LinkedHashSet make any guarantees as to which of several duplicates are kept from the list? For instance, if position 1, 3, and 5 are duplicates in the original list, can we assume that this process will remove 3 and 5? Or maybe remove 1 and 3? Thanks. – Matt Briançon May 01 '11 at 02:20
  • 18
    @Matt: yes, it does guarantee that. The [docs](http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html) say: "This linked list defines the iteration ordering, which is the order in which elements were inserted into the set (insertion-order). Note that insertion order is not affected if an element is re-inserted into the set." – abahgat May 02 '11 at 09:00
  • Very interesting. I have a different situation here. I am not trying to sort String but another object called AwardYearSource. This class has an int attribute called year. So I want to remove duplicates based on the year. i.e if there is year 2010 mentioned more than once, I want to remove that AwardYearSource object. How can I do that? – WowBow Apr 16 '12 at 15:27
  • @WowBow For example you can define Wrapper object which holds AwardYearSource. And define this Wrapper objects equals method based on AwardYearSources year field. Then you can use Set with these Wrapper objects. – Ondrej Bozek Jun 20 '12 at 12:19
  • @WowBow or implement Comparable/Comparator – shrini1000 Jan 11 '13 at 05:09
174

In Java 8:

List<String> deduped = list.stream().distinct().collect(Collectors.toList());

Please note that the hashCode-equals contract for list members should be respected for the filtering to work properly.

Community
  • 1
  • 1
Vitalii Fedorenko
  • 110,878
  • 29
  • 149
  • 111
  • 1
    How do i do this for case insensitive distinct ? – StackFlowed Sep 13 '16 at 20:04
  • @StackFlowed If you don't need to preserve the order of the list you can `addAll` to `new TreeSet(String.CASE_INSENSITIVE_ORDER)`. The first element added will remain in the set so if your list contains "Dog" and "dog" (in that order) the `TreeSet` will contain "Dog". If order must be preserved then before the line in the answer put `list.replaceAll(String::toUpperCase);`. – Paul Nov 03 '17 at 23:28
  • 1
    I am getting this error :incompatible types: List cannot be converted to List – Samir Apr 04 '18 at 14:34
  • This is a simple solution in general but how do you remove the duplicates from an Arraylist of int[]? – Laser Infinite Jan 23 '20 at 20:13
76

Suppose we have a list of String like:

List<String> strList = new ArrayList<>(5);
// insert up to five items to list.        

Then we can remove duplicate elements in multiple ways.

Prior to Java 8

List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));

Note: If we want to maintain the insertion order then we need to use LinkedHashSet in place of HashSet

Using Guava

List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));

Using Java 8

List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());

Note: In case we want to collect the result in a specific list implementation e.g. LinkedList then we can modify the above example as:

List<String> deDupStringList3 = strList.stream().distinct()
                 .collect(Collectors.toCollection(LinkedList::new));

We can use parallelStream also in the above code but it may not always give expected performance benefits. Check this question for more.

akhil_mittal
  • 23,309
  • 7
  • 96
  • 95
  • Yah, When i typed my previous comments, I was in a impression that `parallel streams` will give better performance always. But it's a myth. I later learned that there are certain scenarios where parallel streams should be used. In this scenario parallel streams will not give any better performance. and yes parallel streams might not give desired results some cases. `List deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());` should be the suitable solution in this case – Diablo Aug 10 '18 at 10:32
53

If you don't want duplicates, use a Set instead of a List. To convert a List to a Set you can use the following code:

// list is some List of Strings
Set<String> s = new HashSet<String>(list);

If really necessary you can use the same construction to convert a Set back into a List.

Benno Richters
  • 15,378
  • 14
  • 42
  • 45
  • Similarly at the bottom of the thread, I have given an answer where I am using Set for Custom Object. In a case if anyone have custom object like "Contact" or "Student" can use that answer that works fine for me. – Muhammad Adil Oct 25 '16 at 14:16
  • The problem comes when you have to specifically access an element. For instance when binding an object to a list item view in Android, you are given its index. So `Set` cannot be used here. – TheRealChx101 Apr 05 '19 at 06:13
  • How can I aproach this when the list is an object list – jvargas Mar 16 '20 at 20:20
30

Java 8 streams provide a very simple way to remove duplicate elements from a list. Using the distinct method. If we have a list of cities and we want to remove duplicates from that list it can be done in a single line -

 List<String> cityList = new ArrayList<>();
 cityList.add("Delhi");
 cityList.add("Mumbai");
 cityList.add("Bangalore");
 cityList.add("Chennai");
 cityList.add("Kolkata");
 cityList.add("Mumbai");

 cityList = cityList.stream().distinct().collect(Collectors.toList());

How to remove duplicate elements from an arraylist

infoj
  • 681
  • 8
  • 4
30

You can also do it this way, and preserve order:

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
Nenad Bulatović
  • 7,238
  • 14
  • 83
  • 113
  • I think this is the best way of removing duplicated in an ArrayList. Definitely recommended. Thank you @Nenad for the answer. – ByWaleed Mar 13 '19 at 09:59
30

Here's a way that doesn't affect your list ordering:

ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();

Iterator iterator = l1.iterator();

while (iterator.hasNext()) {
    YourClass o = (YourClass) iterator.next();
    if(!l2.contains(o)) l2.add(o);
}

l1 is the original list, and l2 is the list without repeated items (Make sure YourClass has the equals method according to what you want to stand for equality)

Pritam Banerjee
  • 17,953
  • 10
  • 93
  • 108
stbn
  • 425
  • 5
  • 4
  • 1
    This answer lacks two things: 1) It does not use generics, but raw types (`ArrayList` should be used instead of `ArrayList`) 2) The explicit iterator creating can be avoided by using a `for (T current : l1) { ... }`. Even if you wanted to use an `Iterator` explicitly, `iterador` is misspelled. – randers Dec 07 '15 at 16:22
  • 9
    And this implementation runs in quadratic time, compared to the linked hash set implementation running in linear time. (i.e. this takes 10 times longer on a list with 10 elements, 10,000 times longer on a list with 10,000 elements. JDK 6 implementation for [ArrayList.contains](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/util/ArrayList.java#ArrayList.indexOf%28java.lang.Object%29), JDK8 impl is the same.) – Patrick M Jul 11 '16 at 16:09
26

this can solve the problem:

private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {

     Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
     for (int i = 0; i < list1.size(); i++) {
         cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
     }
     List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
     return list;
}
Pritam Banerjee
  • 17,953
  • 10
  • 93
  • 108
user2868724
  • 269
  • 3
  • 2
21

It is possible to remove duplicates from arraylist without using HashSet or one more arraylist.

Try this code..

    ArrayList<String> lst = new ArrayList<String>();
    lst.add("ABC");
    lst.add("ABC");
    lst.add("ABCD");
    lst.add("ABCD");
    lst.add("ABCE");

    System.out.println("Duplicates List "+lst);

    Object[] st = lst.toArray();
      for (Object s : st) {
        if (lst.indexOf(s) != lst.lastIndexOf(s)) {
            lst.remove(lst.lastIndexOf(s));
         }
      }

    System.out.println("Distinct List "+lst);

Output is

Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
CarlJohn
  • 727
  • 2
  • 9
  • 20
21

There is also ImmutableSet from Guava as an option (here is the documentation):

ImmutableSet.copyOf(list);
randers
  • 5,031
  • 5
  • 37
  • 64
Timofey Gorshkov
  • 4,987
  • 6
  • 41
  • 66
  • 2
    Note that there is an `ImmutableSet.asList()` method, returning an `ImmutableList`, if you need it back as a `List`. – Andy Turner Oct 27 '17 at 19:25
12

Probably a bit overkill, but I enjoy this kind of isolated problem. :)

This code uses a temporary Set (for the uniqueness check) but removes elements directly inside the original list. Since element removal inside an ArrayList can induce a huge amount of array copying, the remove(int)-method is avoided.

public static <T> void removeDuplicates(ArrayList<T> list) {
    int size = list.size();
    int out = 0;
    {
        final Set<T> encountered = new HashSet<T>();
        for (int in = 0; in < size; in++) {
            final T t = list.get(in);
            final boolean first = encountered.add(t);
            if (first) {
                list.set(out++, t);
            }
        }
    }
    while (out < size) {
        list.remove(--size);
    }
}

While we're at it, here's a version for LinkedList (a lot nicer!):

public static <T> void removeDuplicates(LinkedList<T> list) {
    final Set<T> encountered = new HashSet<T>();
    for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
        final T t = iter.next();
        final boolean first = encountered.add(t);
        if (!first) {
            iter.remove();
        }
    }
}

Use the marker interface to present a unified solution for List:

public static <T> void removeDuplicates(List<T> list) {
    if (list instanceof RandomAccess) {
        // use first version here
    } else {
        // use other version here
    }
}

EDIT: I guess the generics-stuff doesn't really add any value here.. Oh well. :)

volley
  • 6,651
  • 1
  • 27
  • 28
  • 1
    Why use ArrayList in parameter? Why not just List? Will that not work? – Shervin Asgari Nov 12 '09 at 15:54
  • A List will absolutely _work_ as in-parameter for the first method listed. The method is however _optimized_ for use with a random access list such as ArrayList, so if a LinkedList is passed instead you will get poor performance. For example, setting the n:th element in a LinkedList takes O(n) time, whereas setting the n:th element in a random access list (such as ArrayList) takes O(1) time. Again, though, this is probably overkill... If you need this kind of specialized code it will hopefully be in an isolated situation. – volley Dec 09 '09 at 20:37
12
public static void main(String[] args){
    ArrayList<Object> al = new ArrayList<Object>();
    al.add("abc");
    al.add('a');
    al.add('b');
    al.add('a');
    al.add("abc");
    al.add(10.3);
    al.add('c');
    al.add(10);
    al.add("abc");
    al.add(10);
    System.out.println("Before Duplicate Remove:"+al);
    for(int i=0;i<al.size();i++){
        for(int j=i+1;j<al.size();j++){
            if(al.get(i).equals(al.get(j))){
                al.remove(j);
                j--;
            }
        }
    }
    System.out.println("After Removing duplicate:"+al);
}
  • This implementation return no element in the list because of the last j-- – neo7 Sep 23 '15 at 09:29
  • 1
    This implementation work's very fine.there is no issue behind this and for this task i am only use one arraylist.so this answer is completely good.before giving negative feedback you shold also add testcase also so that every one can understand the result.Thanks Manash – Manash Ranjan Dakua Sep 24 '15 at 13:14
5

If you're willing to use a third-party library, you can use the method distinct() in Eclipse Collections (formerly GS Collections).

ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
    FastList.newListWith(1, 3, 2),
    integers.distinct());

The advantage of using distinct() instead of converting to a Set and then back to a List is that distinct() preserves the order of the original List, retaining the first occurrence of each element. It's implemented by using both a Set and a List.

MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
    T item = list.get(i);
    if (seenSoFar.add(item))
    {
        targetCollection.add(item);
    }
}
return targetCollection;

If you cannot convert your original List into an Eclipse Collections type, you can use ListAdapter to get the same API.

MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();

Note: I am a committer for Eclipse Collections.

Donald Raab
  • 6,458
  • 2
  • 36
  • 44
Craig P. Motlin
  • 26,452
  • 17
  • 99
  • 126
5

If you are using model type List< T>/ArrayList< T> . Hope,it's help you.

Here is my code without using any other data structure like set or hashmap

for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {       
 if (Models.get(i).getName().equals(Models.get(j).getName())) {    
 Models.remove(j);
   j--;
  }
 }
}
3

If you want to preserve your Order then it is best to use LinkedHashSet. Because if you want to pass this List to an Insert Query by Iterating it, the order would be preserved.

Try this

LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);

This conversion will be very helpful when you want to return a List but not a Set.

RAS
  • 8,100
  • 16
  • 64
  • 86
ram
  • 149
  • 1
  • 4
  • 10
3

This three lines of code can remove the duplicated element from ArrayList or any collection.

List<Entity> entities = repository.findByUserId(userId);

Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
2

Code:

List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);

Note: Definitely, there will be memory overhead.

almightyGOSU
  • 3,731
  • 6
  • 31
  • 41
sambhu
  • 111
  • 1
  • 5
2
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");

HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
Hardip
  • 360
  • 3
  • 9
2

you can use nested loop in follow :

ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();

        Iterator iterator1 = l1.iterator();
        boolean repeated = false;

        while (iterator1.hasNext())
        {
            Class1 c1 = (Class1) iterator1.next();
            for (Class1 _c: l2) {
                if(_c.getId() == c1.getId())
                    repeated = true;
            }
            if(!repeated)
                l2.add(c1);
        }
HamidReza
  • 1,726
  • 20
  • 15
  • Perfect - just missing "repeated = false;" in the internal loop after the "if(!repeated) l2.add(c1);" otherwise it return a short list – kfir Aug 23 '21 at 06:25
2

When you are filling the ArrayList, use a condition for each element. For example:

    ArrayList< Integer > al = new ArrayList< Integer >(); 

    // fill 1 
    for ( int i = 0; i <= 5; i++ ) 
        if ( !al.contains( i ) ) 
            al.add( i ); 

    // fill 2 
    for (int i = 0; i <= 10; i++ ) 
        if ( !al.contains( i ) ) 
            al.add( i ); 

    for( Integer i: al )
    {
        System.out.print( i + " ");     
    }

We will get an array {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

MantaMan
  • 137
  • 1
  • 1
  • 11
HarpyWar
  • 113
  • 1
  • 5
2
for(int a=0;a<myArray.size();a++){
        for(int b=a+1;b<myArray.size();b++){
            if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
                myArray.remove(b); 
                dups++;
                b--;
            }
        }
}
Ghyour
  • 31
  • 1
1

LinkedHashSet will do the trick.

String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
    System.out.println(s1);

System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
     System.out.println(arr3[i].toString());

//output: 5,1,2,3,4

user1912383
  • 359
  • 2
  • 6
  • 16
1

As said before, you should use a class implementing the Set interface instead of List to be sure of the unicity of elements. If you have to keep the order of elements, the SortedSet interface can then be used; the TreeSet class implements that interface.

Yoon5oo
  • 496
  • 5
  • 11
Vinze
  • 2,549
  • 3
  • 22
  • 23
1
        List<String> result = new ArrayList<String>();
        Set<String> set = new LinkedHashSet<String>();
        String s = "ravi is a good!boy. But ravi is very nasty fellow.";
        StringTokenizer st = new StringTokenizer(s, " ,. ,!");
        while (st.hasMoreTokens()) {
            result.add(st.nextToken());
        }
         System.out.println(result);
         set.addAll(result);
        result.clear();
        result.addAll(set);
        System.out.println(result);

output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
siva
  • 11
  • 1
1

This is used for your Custom Objects list

   public List<Contact> removeDuplicates(List<Contact> list) {
    // Set set1 = new LinkedHashSet(list);
    Set set = new TreeSet(new Comparator() {

        @Override
        public int compare(Object o1, Object o2) {
            if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
                    ((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);

    final List newList = new ArrayList(set);
    return newList;
}
0
import java.util.*;
class RemoveDupFrmString
{
    public static void main(String[] args)
    {

        String s="appsc";

        Set<Character> unique = new LinkedHashSet<Character> ();

        for(char c : s.toCharArray()) {

            System.out.println(unique.add(c));
        }
        for(char dis:unique){
            System.out.println(dis);
        }


    }
}
Pigueiras
  • 18,778
  • 10
  • 64
  • 87
reddy
  • 1
0
public Set<Object> findDuplicates(List<Object> list) {
        Set<Object> items = new HashSet<Object>();
        Set<Object> duplicates = new HashSet<Object>();
        for (Object item : list) {
            if (items.contains(item)) {
                duplicates.add(item);
                } else { 
                    items.add(item);
                    } 
            } 
        return duplicates;
        }
Harsha
  • 39
  • 1
  • 7
0
    ArrayList<String> list = new ArrayList<String>();
    HashSet<String> unique = new LinkedHashSet<String>();
    HashSet<String> dup = new LinkedHashSet<String>();
    boolean b = false;
    list.add("Hello");
    list.add("Hello");
    list.add("how");
    list.add("are");
    list.add("u");
    list.add("u");

    for(Iterator iterator= list.iterator();iterator.hasNext();)
    {
        String value = (String)iterator.next();
        System.out.println(value);

        if(b==unique.add(value))
            dup.add(value);
        else
            unique.add(value);


    }
    System.out.println(unique);
    System.out.println(dup);
SparkOn
  • 8,806
  • 4
  • 29
  • 34
0

If you want to remove duplicates from ArrayList means find the below logic,

public static Object[] removeDuplicate(Object[] inputArray)
{
    long startTime = System.nanoTime();
    int totalSize = inputArray.length;
    Object[] resultArray = new Object[totalSize];
    int newSize = 0;
    for(int i=0; i<totalSize; i++)
    {
        Object value = inputArray[i];
        if(value == null)
        {
            continue;
        }

        for(int j=i+1; j<totalSize; j++)
        {
            if(value.equals(inputArray[j]))
            {
                inputArray[j] = null;
            }
        }
        resultArray[newSize++] = value;
    }

    long endTime = System.nanoTime()-startTime;
    System.out.println("Total Time-B:"+endTime);
    return resultArray;
}
Thananjayan N
  • 77
  • 1
  • 3
  • 1
    Why would you post a quadratic solution to a question that already has 2-year-old linear and log-linear solutions, that are also simpler? – abarnert Sep 11 '14 at 07:40
0

The @jonathan-stafford solution is OK. But this don't preserve the list order.

If you want preserve the list order you have to use this:

public static <T> void removeDuplicate(List <T> list) {
Set <T> set = new HashSet <T>();
List <T> newList = new ArrayList <T>();
for (Iterator <T>iter = list.iterator();    iter.hasNext(); ) {
   Object element = iter.next();
   if (set.add((T) element))
      newList.add((T) element);
   }
   list.clear();
   list.addAll(newList);
}

It's only to complete the answer. Very good!

sharkbait
  • 2,980
  • 16
  • 51
  • 89
  • 2
    When you use `T element = iter.next();`, you don’t need the unchecked type casts. Or you use `for(T element: list) …` instead of dealing with an `Iterator` manually. – Holger Jul 04 '19 at 09:58
0

Here is my answer without using any other data structure like set or hashmap etc.

public static <T> ArrayList<T> uniquefy(ArrayList<T> myList) {

    ArrayList <T> uniqueArrayList = new ArrayList<T>();
    for (int i = 0; i < myList.size(); i++){
        if (!uniqueArrayList.contains(myList.get(i))){
            uniqueArrayList.add(myList.get(i));
        }
    }

    return uniqueArrayList;
}
neo7
  • 654
  • 5
  • 14
  • 1
    “without using any other data structure”, except another `ArrayList`. Which will be very inefficient for larger lists. – Holger Jul 04 '19 at 09:59
0

Would something like this work better ?

public static void removeDuplicates(ArrayList<String> list) {
    Arraylist<Object> ar     = new Arraylist<Object>();
    Arraylist<Object> tempAR = new Arraylist<Object>();
    while (list.size()>0){
        ar.add(list(0));
        list.removeall(Collections.singleton(list(0)));
    }
    list.addAll(ar);
}

That should maintain the order and also not be quadratic in run time.

logi-kal
  • 7,107
  • 6
  • 31
  • 43
  • 1
    “…and also not be quadratic in run time” *Of course*, this *is* quadratic in run time. It’s even worse than other quadratic solutions. – Holger Jul 04 '19 at 10:02
0

Time Complexity : O(n) : Without Set

private static void removeDup(ArrayList<String> listWithDuplicateElements) {
    System.out.println(" Original Duplicate List :" + listWithDuplicateElements);
    List<String> listWithoutDuplicateElements = new ArrayList<>(listWithDuplicateElements.size());

    listWithDuplicateElements.stream().forEach(str -> {
        if (listWithoutDuplicateElements.indexOf(str) == -1) {
            listWithoutDuplicateElements.add(str);
        }
    });     

    System.out.println(" Without Duplicate List :" + listWithoutDuplicateElements);
}
0

This is the right one (if you are concerned about the overhead of HashSet.

 public static ArrayList<String> removeDuplicates (ArrayList<String> arrayList){
    if (arrayList.isEmpty()) return null;  //return what makes sense for your app
    Collections.sort(arrayList, String.CASE_INSENSITIVE_ORDER);
    //remove duplicates
    ArrayList <String> arrayList_mod = new ArrayList<>();
    arrayList_mod.add(arrayList.get(0));
    for (int i=1; i<arrayList.size(); i++){
        if (!arrayList.get(i).equals(arrayList.get(i-1))) arrayList_mod.add(arrayList.get(i));
    }
    return arrayList_mod;
}
seekingStillness
  • 4,833
  • 5
  • 38
  • 68
  • 1
    “if you are concerned about the overhead of HashSet” and are ignorant towards the overhead of `Collectiors.sort`… – Holger Jul 04 '19 at 12:34
0
Set<String> strSet = strList.stream().collect(Collectors.toSet());

Is the easiest way to remove your duplicates.

saif
  • 1,182
  • 14
  • 27
0

If you want your list to automatically ignore duplicates and preserve its order, you could create a HashList(a HashMap embedded List).

public static class HashList<T> extends ArrayList<T>{
        private HashMap <T,T> hashMap;
        public HashList(){
            hashMap=new HashMap<>();
        }

        @Override
        public boolean add(T t){
            if(hashMap.get(t)==null){
                hashMap.put(t,t);
                return super.add(t);
            }else return false;
        }

        @Override
        public boolean addAll(Collection<? extends T> c){
            HashList<T> addup=(HashList<T>)c;
            for(int i=0;i<addup.size();i++){
                add(addup.get(i));
            }return true;
        }

    }

Usage Example:

HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);
linker
  • 821
  • 1
  • 8
  • 20
  • 2
    Try `ListIterator i = hashList.listIterator(); i.add("hello"); i.add("hello");`. Alternatively, you can use `hashList.add("a"); hashList.add("b"); hashList.replaceAll(x -> "hello");`. And there might be more ways to counteract this approach in the future. The takeaway is that you shouldn’t try to enforce new contracts via subclassing with classes not designed for that. You will find more about this topic when you search for the “*Prefer composition over inheritance*” OOP rule. – Holger Jul 04 '19 at 12:41
  • that makes a lot of sense – linker Sep 27 '20 at 14:45
0

Here is a solution that works with any object:

public static <T> List<T> clearDuplicates(List<T> messages,Comparator<T> comparator) {
    List<T> results = new ArrayList<T>();
    for (T m1 : messages) {
        boolean found = false;
        for (T m2 : results) {
            if (comparator.compare(m1,m2)==0) {
                found=true;
                break;
            }
        }
        if (!found) {
            results.add(m1);
        }
    }
    return results;
}
Gil SH
  • 3,789
  • 1
  • 27
  • 25
0

Kotlin

val list = listOf('a', 'A', 'b', 'B', 'A', 'a')
println(list.distinct()) // [a, A, b, B]
println(list.distinctBy { it.uppercaseChar() }) // [a, b]

from here kotlinlang

Kirguduck
  • 748
  • 1
  • 9
  • 20
-1

In Java, List permits ordered access of their elements. They can have duplicates because their lookup key is the position not some hash code, every element can be modified while they remain in the list where as Set represents a collection of unique elements and while elements are in set, they must not be modified.While there is no restriction preventing you from modifying elements in a set, if an element is modified, then it could become forever lost in the set.

public static void main(String[] args) {
       List<String> l = new ArrayList<String>();
       l.add("A");
       l.add("B");
       l.add("C");
       l.add("A");
       System.out.println("Before removing duplicates: ");
       for (String s : l) {
            System.out.println(s);
       }
       Set<String> set = new HashSet<String>(l);
       List<String> newlist = new ArrayList<String>(set);
       System.out.println("after removing duplicates: ");
       for (String s : newlist) {
            System.out.println(s);
       }
  }

for reference, refer this link How to remove duplicates from ArrayList

logi-kal
  • 7,107
  • 6
  • 31
  • 43
satish
  • 1,571
  • 1
  • 11
  • 4