How do I remove repeated elements from ArrayList?

后端 未结 30 1325
难免孤独
难免孤独 2020-11-21 06:24

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

相关标签:
30条回答
  • 2020-11-21 06:32

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

    ImmutableSet.copyOf(list);
    
    0 讨论(0)
  • 2020-11-21 06:33

    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.

    0 讨论(0)
  • 2020-11-21 06:34

    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 give expected performace benefits. Check this question for more.

    0 讨论(0)
  • 2020-11-21 06:35

    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. :)

    0 讨论(0)
  • 2020-11-21 06:36
    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);
            }
    
    
        }
    }
    
    0 讨论(0)
  • 2020-11-21 06:38

    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.

    0 讨论(0)
提交回复
热议问题