Java 从 ArrayList 中删除重复值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21985397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:50:47  来源:igfitidea点击:

Removing Duplicate Values from ArrayList

javalistsortingarraylist

提问by Krishna

I have one Arraylist of String and I have added Some Duplicate Value in that. and i just wanna remove that Duplicate value So how to remove it.

我有一个字符串数组列表,并且在其中添加了一些重复值。我只想删除那个重复值 那么如何删除它。

Here Example I got one Idea.

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

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

But is there any Sufficient way remove that Duplicate form list. with out using For loop ? And ya i can do it by using HashSet or some other way but using array list only. would like to have your suggestion for that. thank you for your answer in advance.

但是有没有足够的方法删除重复的表单列表。不使用 For 循环?而且我可以通过使用 HashSet 或其他方式但仅使用数组列表来做到这一点。想听听您的建议。提前感谢您的回答。

采纳答案by Marco13

You can create a LinkedHashSetfrom the list. The LinkedHashSetwill contain each element only once, and in the same order as the List. Then create a new Listfrom this LinkedHashSet. So effectively, it's a one-liner:

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

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

Any approach that involves List#containsor List#removewill probably decrease the asymptotic running time from O(n) (as in the above example) to O(n^2).

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



EDITFor the requirement mentioned in the comment: If you want to remove duplicate elements, but consider the Strings as equalignoring the case, then you could do something like this:

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

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

It will have a running time of O(n*logn), which is still better than many other options. Note that this looks a little bit more complicated than it might have to be: I assumed that the orderof the elements in the list may not be changed. If the order of the elements in the list does not matter, you can simply do

它将有 O(n*logn) 的运行时间,这仍然比许多其他选项要好。请注意,这看起来比实际情况要复杂一些:我假设列表中元素的顺序可能不会改变。如果列表中元素的顺序无关紧要,你可以简单地做

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

回答by Ruchira Gayan Ranaweera

This will be the best way

这将是最好的方法

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

回答by stinepike

if you want to use only arraylist then I am worried there is no better way which will create a huge performance benefit. But by only using arraylist i would check before adding into the list like following

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

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

In this cases using a Set is suitable.

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

回答by Furquan Khan

It is better to use HastSet

最好使用HastSet

1-a) A HashSet holds a set of objects, but in a way that it allows you to easily and quickly determine whether an object is already in the set or not. It does so by internally managing an array and storing the object using an index which is calculated from the hashcode of the object. Take a look here

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

1-b) HashSet is an unordered collection containing unique elements. It has the standard collection operations Add, Remove, Contains, but since it uses a hash-based implementation, these operation are O(1). (As opposed to List for example, which is O(n) for Contains and Remove.) HashSet also provides standard set operations such as union, intersection, and symmetric difference.Take a look here

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

2) There are different implementations of Sets. Some make insertion and lookup operations super fast by hashing elements. However that means that the order in which the elements were added is lost. Other implementations preserve the added order at the cost of slower running times.

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

The HashSet class in C# goes for the first approach, thus not preserving the order of elements. It is much faster than a regular List. Some basic benchmarks showed that HashSet is decently faster when dealing with primary types (int, double, bool, etc.). It is a lot faster when working with class objects. So that point is that HashSet is fast.

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

The only catch of HashSet is that there is no access by indices. To access elements you can either use an enumerator or use the built-in function to convert the HashSet into a List and iterate through that.Take a look here

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

回答by Shishir Kumar

You can make use of Google Guava utilities, as shown below

可以使用谷歌Guava工具,如下图

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

This is probably the most efficient way of eliminating the duplicates from the list and interestingly, it preservesthe iteration order as well.

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

UPDATE

更新

But, in case, you don't want to involve Guava then duplicates can be removed as shown below.

但是,如果您不想涉及 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);

But, of course, this will destroys the iteration order of the elements in the ArrayList.

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

Shishir

石狮

回答by Weibo Li

Without a loop, No! Since ArrayListis indexed by order rather than by key, you can not found the target element without iterate the whole list.

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

A good practice of programming is to choose proper data structure to suit your scenario. So if Setsuits your scenario the most, the discussion of implementing it with Listand trying to find the fastest way of using an improper data structure makes no sense.

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

回答by RaviSoni

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

回答by Manojkumar

I don't think the list = new ArrayList<String>(new LinkedHashSet<String>(list))is not the best way , since we are using the LinkedHashset(We could use directly LinkedHashsetinstead of ArrayList),

我不认为这list = new ArrayList<String>(new LinkedHashSet<String>(list))不是最好的方法,因为我们使用的是 LinkedHashset(我们可以直接使用LinkedHashset而不是ArrayList),

Solution:

解决方案:

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

Output: [1, 2, 3]

输出:[1, 2, 3]

Here I am extending the ArrayList, as I am using the it with some changes by overriding the addmethod.

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

回答by Brice Roncace

Using java 8:

使用 Java 8:

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

回答by BRIJ

Simple function for removing duplicates from list

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

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

Example:
Input: [1, 2, 2, 3, 1, 3, 3, 2, 3, 1, 2, 3, 3, 4, 4, 4, 1]
Output: [1, 2, 3, 4]

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