从ArrayList中删除重复值

时间:2014-02-24 10:41:02

标签: java list sorting arraylist

我有一个字符串的Arraylist,我在其中添加了一些重复值。我只是想删除重复值,所以如何删除它。

这里的例子我有一个想法。

List<String> list = new ArrayList<String>();
        list.add("Krishna");
        list.add("Krishna");
        list.add("Kishan");
        list.add("Krishn");
        list.add("Aryan");
        list.add("Harm");

        System.out.println("List"+list);

        for (int i = 1; i < list.size(); i++) {
            String a1 = list.get(i);
            String a2 = list.get(i-1);
            if (a1.equals(a2)) {
                list.remove(a1);
            }
        }

        System.out.println("List after short"+list);

但是有没有足够的方法删除重复的表单列表。没有使用For循环? 你可以通过使用HashSet或其他方式,但只使用数组列表。 我想对此有你的建议。谢谢你提前回答。

18 个答案:

答案 0 :(得分:59)

您可以从列表中创建LinkedHashSetLinkedHashSet仅包含每个元素一次,其顺序与List相同。然后从此List创建一个新的LinkedHashSet。如此有效,它是一个单行:

list = new ArrayList<String>(new LinkedHashSet<String>(list))

任何涉及List#containsList#remove的方法都可能会将渐近运行时间从O(n)(如上例所示)减少到O(n ^ 2)。


编辑对于评论中提到的要求:如果要删除重复元素,但将字符串视为相等忽略大小写,那么您可以执行类似的操作这样:

Set<String> toRetain = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
toRetain.addAll(list);
Set<String> set = new LinkedHashSet<String>(list);
set.retainAll(new LinkedHashSet<String>(toRetain));
list = new ArrayList<String>(set);

它的运行时间为O(n * logn),仍然比许多其他选项更好。请注意,这看起来比它可能要复杂得多:我假设列表中元素的 order 可能不会更改。如果列表中元素的顺序无关紧要,您只需执行

即可
Set<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
set.addAll(list);
list = new ArrayList<String>(set);

答案 1 :(得分:11)

如果你只想使用arraylist那么我担心没有更好的方法可以创造巨大的性能优势。但是只使用arraylist我会在添加到列表之前检查,如下所示

void addToList(String s){
  if(!yourList.contains(s))
       yourList.add(s);
}

在这种情况下使用Set是合适的。

答案 2 :(得分:9)

您可以使用Google Guava实用程序,如下所示

 list = ImmutableSet.copyOf(list).asList(); 

这可能是从列表中删除重复项的最有效方法,有趣的是,保留迭代顺序。

<强>更新

但是,如果您不想涉及Guava,则可以删除重复项,如下所示。

ArrayList<String> list = new ArrayList<String>();
    list.add("Krishna");
    list.add("Krishna");
    list.add("Kishan");
    list.add("Krishn");
    list.add("Aryan");
    list.add("Harm");

System.out.println("List"+list);
HashSet hs = new HashSet();
hs.addAll(list);
list.clear();
list.addAll(hs);

但是,当然,这将破坏ArrayList中元素的迭代顺序。

Shishir

答案 3 :(得分:6)

Java 8 流功能

您可以使用上面的distinct函数来获取列表的不同元素

stringList.stream().distinct();

从文档中

  

返回由此流的不同元素(根据Object.equals(Object))组成的流。

另一种方法是,如果你不想使用equals方法就是使用这样的collect函数,

stringList.stream()  
    .collect(Collectors.toCollection(() -> 
        new TreeSet<String>((p1, p2) -> p1.compareTo(p2)) 
));  

从文档中

  

使用收集器对此流的元素执行可变减少操作。

希望有所帮助。

答案 4 :(得分:3)

List<String> list = new ArrayList<String>();
        list.add("Krishna");
        list.add("Krishna");
        list.add("Kishan");
        list.add("Krishn");
        list.add("Aryan");
        list.add("Harm");

HashSet<String> hs=new HashSet<>(list);

System.out.println("=========With Duplicate Element========");
System.out.println(list);
System.out.println("=========Removed Duplicate Element========");
System.out.println(hs);

答案 5 :(得分:2)

从列表中删除重复项的简单功能

private void removeDuplicates(List<?> list)
{
    int count = list.size();

    for (int i = 0; i < count; i++) 
    {
        for (int j = i + 1; j < count; j++) 
        {
            if (list.get(i).equals(list.get(j)))
            {
                list.remove(j--);
                count--;
            }
        }
    }
}

例:
输入:[1,2,3,3,1,3,3,2,3,1,2,3,3,4,4,4,1]
输出:[1,2,3,4]

答案 6 :(得分:2)

     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)2).getId()) ) {
                return 0;
            }
            return 1;
        }
    });
    set.addAll(list);
    final List newList = new ArrayList(set);
    return newList;
}

答案 7 :(得分:2)

我认为list = new ArrayList<String>(new LinkedHashSet<String>(list))不是最佳方式,因为我们使用的是LinkedHashset(我们可以直接使用LinkedHashset代替ArrayList),

解决方案:

import java.util.ArrayList;
public class Arrays extends ArrayList{

@Override
public boolean add(Object e) {
    if(!contains(e)){
        return super.add(e);
    }else{
        return false;
    }
}

public static void main(String[] args) {
    Arrays element=new Arrays();
    element.add(1);
    element.add(2);
    element.add(2);
    element.add(3);

    System.out.println(element);
}
}

输出: [1,2,3]

我在这里扩展ArrayList,因为我通过覆盖add方法进行了一些更改。

答案 8 :(得分:1)

这将是最好的方式

    List<String> list = new ArrayList<String>();
    list.add("Krishna");
    list.add("Krishna");
    list.add("Kishan");
    list.add("Krishn");
    list.add("Aryan");
    list.add("Harm");

    Set<String> set=new HashSet<>(list);

答案 9 :(得分:1)

没有循环,!由于ArrayList是按顺序而不是按键索引的,因此如果不迭代整个列表,就无法找到目标元素。

编程的一个好习惯是选择适合您场景的数据结构。因此,如果Set最适合您的场景,那么使用List实现它并尝试找到使用不正确数据结构的最快方法的讨论毫无意义。

答案 10 :(得分:1)

最好使用HastSet

1-a)HashSet包含一组对象,但它允许您轻松快速地确定对象是否已存在于集合中。它通过内部管理数组并使用从对象的哈希码计算的索引存储对象来实现。看看这里

1-b)HashSet是一个包含唯一元素的无序集合。它具有标准的集合操作Add,Remove,Contains,但由于它使用基于散列的实现,因此这些操作是O(1)。 (与List相反,例如,对于Contains和Remove,它是O(n)。)HashSet还提供标准集合操作,例如并集,交集和对称差异。看看这里

2)集合有不同的实现。有些通过散列元素使插入和查找操作超快。但是,这意味着添加元素的顺序将丢失。其他实现以较慢的运行时间为代价来保留添加的顺序。

C#中的HashSet类用于第一种方法,因此不保留元素的顺序。它比常规列表快得多。一些基本的基准测试表明,在处理主要类型(int,double,bool等)时,HashSet的速度要快得多。使用类对象时速度要快得多。所以关键是HashSet很快。

HashSet的唯一问题是索引无法访问。要访问元素,您可以使用枚举器或使用内置函数将HashSet转换为List并迭代它。看看这里

答案 11 :(得分:1)

    barchart.Series[0].IsValueShownAsLabel = false;

这是更好的方法

答案 12 :(得分:1)

GridLayout
这可能是使用Java8 Stream API的解决方案之一。希望这可以帮助。

答案 13 :(得分:1)

 public void removeDuplicates() {
    ArrayList<Object> al = new ArrayList<Object>();
    al.add("java");
    al.add('a');
    al.add('b');
    al.add('a');
    al.add("java");
    al.add(10.3);
    al.add('c');
    al.add(14);
    al.add("java");
    al.add(12);

    System.out.println("Before Remove Duplicate elements:" + 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 elements:" + al);
}

在删除重复元素之前:

[java, a, b, a, java, 10.3, c, 14, java, 12]

删除重复元素后:

[java, a, b, 10.3, c, 14, 12]

答案 14 :(得分:0)

使用java 8:

public static <T> List<T> removeDuplicates(List<T> list) {
    return list.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList());
}

答案 15 :(得分:0)

如果你只需要使用ArrayList删除重复项,没有其他Collection类,那么: -

//list is the original arraylist containing the duplicates as well
List<String> uniqueList = new ArrayList<String>();
    for(int i=0;i<list.size();i++) {
        if(!uniqueList.contains(list.get(i)))
            uniqueList.add(list.get(i));
    }

希望这有帮助!

答案 16 :(得分:0)

private static void removeDuplicates(List<Integer> list)
{
    Collections.sort(list);
    int count = list.size();
    for (int i = 0; i < count; i++) 
    {
        if(i+1<count && list.get(i)==list.get(i+1)){
            list.remove(i);
            i--;
            count--;
        }
    }
}

答案 17 :(得分:0)

public static List<String> removeDuplicateElements(List<String> array){
    List<String> temp = new ArrayList<String>();
    List<Integer> count = new ArrayList<Integer>();
    for (int i=0; i<array.size()-2; i++){
        for (int j=i+1;j<array.size()-1;j++)
            {
                if (array.get(i).compareTo(array.get(j))==0) {
                    count.add(i);
                    int kk = i;
                }
            }
        }
        for (int i = count.size()+1;i>0;i--) {
            array.remove(i);
        }
        return array;
    }
}