当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何从ArrayList中删除重复的元素?》经验,为你挑选了14个好方法。

我有一个ArrayList,我想从中删除重复的字符串.我怎样才能做到这一点?



1> jonathan-sta..:

如果您不想在a中重复Collection,您应该考虑为什么使用Collection允许重复的重复项.删除重复元素的最简单方法是将内容添加到Set(不允许重复),然后将其添加SetArrayList:

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

当然,这破坏了元素的排序ArrayList.


如果您希望保留订单,另请参阅LinkedHashSet.
您可以使用`new HashSet(al)`清除它,而不是将其初始化为空并调用`addAll`.
一个好的做法是使用接口类型`List`和`Set`定义变量(而不是像你的例子中的实现类型`ArrayList`和`HashSet`).
@Chetan在O(n)中查找ArrayList中的所有重复项,重要的是在列表中对象上正确定义equals方法(数字没问题):`public Set findDuplicates(List list) {Set items = new HashSet (); 设置 duplicates = new HashSet (); for(Object item:list){if(items.contains(item)){duplicates.add(item); } else {items.add(item); 返回重复; }`

2> abahgat..:

虽然转换ArrayListHashSet有效删除重复项,但如果您需要保留插入顺序,我建议您使用此变体

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

然后,如果您需要返回List引用,则可以再次使用转换构造函数.


@Matt:是的,确实可以保证.[docs](http://download.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html)说:"这个链表定义了迭代顺序,它是元素的顺序.插入到集合中(插入顺序).请注意,如果将元素重新插入集合中,则插入顺序不会受到影响."
LinkedHashSet是否保证列表中保留了多个重复项中的哪一个?例如,如果位置1,3和5在原始列表中是重复的,我们可以假设此过程将删除3和5吗?或者可以删除1和3?谢谢.

3> Vitalii Fedo..:

在Java 8中:

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

请注意,应该尊重列表成员的hashCode-equals合同,以使过滤正常工作.



4> i_am_zero..:

假设我们有一个String类似的列表:

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

然后我们可以通过多种方式删除重复的元素.

在Java 8之前

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

注意:如果我们想要维护插入顺序,那么我们需要使用LinkedHashSet代替HashSet

使用番石榴

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

使用Java 8

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

注意: 如果我们想要在特定列表实现中收集结果,例如,LinkedList我们可以将上面的示例修改为:

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

我们也parallelStream可以在上面的代码中使用,但它可能不会给出预期的性能优势.查看此问题了解更多信息.


+1 Java 8流.但如果不需要区分大小写,则只能轻松修改Java 8解决方案.`List deDupStringList3 = stringList.parallelStream().map(String :: toLowerCase).distinct().collect(Collectors.toList());`应该工作.

5> Benno Richte..:

如果您不想要重复,请使用Set而不是a List.要将a转换List为a,Set您可以使用以下代码:

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

如果真的有必要,你可以使用相同的结构将一个Set回转换成一个List.



6> Nenad Bulato..:

你也可以这样做,并保持秩序:

// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList(new LinkedHashSet(myArrayList));



7> 小智..:

这是一种不影响列表排序的方法:

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是原始列表,l2是没有重复项目的列表(确保YourClass根据你想要的平等对应的方法)


与在线性时间内运行的链接哈希集实现相比,此实现在二次时间内运行.(即,在包含10个元素的列表中,这需要长10倍,在包含10,000个元素的列表上需要长10,000倍.[ArrayList.contains]的JDK 6实现(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是相同的.)

8> 小智..:

Java 8流提供了一种从列表中删除重复元素的非常简单的方法.使用不同的方法.如果我们有一个城市列表,并且我们想从该列表中删除重复项,则可以在一行中完成 -

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

如何从arraylist中删除重复的元素



9> Timofey Gors..:

还有ImmutableSet从番石榴作为一个选项(这里是文档):

ImmutableSet.copyOf(list);



10> CarlJohn..:

可以在不使用HashSet一个 arraylist的情况下从arraylist中删除重复项.

试试这个代码..

    ArrayList lst = new ArrayList();
    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);

输出是

Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]


你是对的,它不是你迭代数组而不是列表.然而,它像地狱一样缓慢.尝试使用几百万个元素.将它与`ImmutableSet.copyOf(lst).toList()`进行比较.

11> 小智..:

这可以解决问题:

private List clearListFromDuplicateFirstName(List list1) {

     Map cleanMap = new LinkedHashMap();
     for (int i = 0; i < list1.size(); i++) {
         cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
     }
     List list = new ArrayList(cleanMap.values());
     return list;
}



12> volley..:

可能有点矫枉过正,但我​​喜欢这种孤立的问题.:)

此代码使用临时Set(用于唯一性检查),但直接删除原始列表中的元素.由于ArrayList中的元素移除会导致大量的数组复制,因此避免了remove(int)方法.

public static  void removeDuplicates(ArrayList list) {
    int size = list.size();
    int out = 0;
    {
        final Set encountered = new HashSet();
        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);
    }
}

虽然我们在这里,但这里是LinkedList的一个版本(好多了!):

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

使用标记界面为List提供统一的解决方案:

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

编辑:我想泛型的东西在这里并没有真正增加任何价值..哦,好吧.:)



13> 小智..:
public static void main(String[] args){
    ArrayList al = new ArrayList();
    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



14> Craig P. Mot..:

如果你愿意使用第三方库,你可以使用的方法distinct()在Eclipse中集(原GS集合).

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

使用distinct()而不是转换为Set然后返回List 的优点是distinct()保留原始List的顺序,保留每个元素的第一次出现.它是通过使用Set和List实现的.

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

如果无法将原始List转换为Eclipse Collections类型,则可以使用ListAdapter获取相同的API.

MutableList distinct = ListAdapter.adapt(integers).distinct();

注意:我是Eclipse Collections的提交者.

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有