如何从ArrayList中删除重复元素?

574
我有一个 ArrayList<String>,我想从中删除重复的字符串。如何做到这一点?
40个回答

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


    }
}

0
如果您想从ArrayList中删除重复项,请查找以下逻辑:
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;
}

1
为什么会发表一个二次解法来回答一个已经有两年历史的线性和对数线性解法,而且那些解法也更简单呢? - abarnert

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

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

0
这样的方式是否更好?
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);
}

这应该能够保持顺序,同时不会在运行时间上呈二次方增长。


1
“…而且不能在运行时间上是二次的” 当然,这在运行时间上是二次的。它甚至比其他二次解决方案还要糟糕。 - Holger

0

这是我的答案,没有使用任何其他数据结构,如set或hashmap等。

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

1
“不使用任何其他数据结构”,除了另一个ArrayList,对于较大的列表来说将非常低效。 - Holger

0
Set<String> strSet = strList.stream().collect(Collectors.toSet());

这是最简单的去重方式。


3
不比 Set<String> strSet = new HashSet<>(strList); 更容易。 - Holger

0
如果您希望列表自动忽略重复项并保留其顺序,您可以创建一个HashList(嵌入式HashMap列表)。
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;
        }

    }

使用示例:

HashList<String> hashlist=new HashList<>();
hashList.add("hello");
hashList.add("hello");
System.out.println(" HashList: "+hashlist);

2
尝试使用ListIterator<String> i = hashList.listIterator(); i.add("hello"); i.add("hello");。或者,您可以使用hashList.add("a"); hashList.add("b"); hashList.replaceAll(x -> "hello");。未来可能会有更多应对此方法的方式。要点是,不应该尝试通过为不设计该方法的类创建子类来强制新合同。搜索“优先选择组合而非继承”面向对象编程规则,可了解更多信息。 - Holger
那很有道理。 - linker

0

如果你关注 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;
}

1
如果你担心HashSet的开销,而对Collectors.sort的开销一无所知... - Holger

-1
在Java中,List允许有序访问它们的元素。它们可以有重复项,因为它们的查找键是位置而不是某个哈希码,每个元素都可以在列表中保持不变,而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);
       }
  }

为了参考,请查看此链接 如何从ArrayList中删除重复项


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接