在不改变元素顺序的情况下删除数组中的重复项

时间:2021-02-28 04:41:00

I have an array, say List<Integer> 139, 127, 127, 139, 130

我有一个数组,比如List 139 127 127 139 130

How to remove duplicates of it and keep its order unchanged? i.e. 139, 127, 130

如何删除它的副本和保持它的顺序不变?即:139、127、130

10 个解决方案

#1


18  

Use an instance of java.util.LinkedHashSet.

使用一个java.util.LinkedHashSet实例。

Set<Integer> set = new LinkedHashSet<>(list);

#2


3  

Construct Set from your list - "A collection that contains no duplicate elements":

从您的列表中构建集合—“不包含重复元素的集合”:

Set<Integer> yourSet = new HashSet<Integer>(yourList);

And convert it back to whatever you want.

然后把它转换成你想要的。

Note: If you want to preserve order, use LinkedHashSet instead.

注意:如果您想保持顺序,请使用LinkedHashSet代替。

#3


2  

With this one-liner:

与这一行程序:

yourList = new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList))

#4


0  

Use LinkedHashSet to remove duplicate and maintain order.

使用LinkedHashSet删除重复并保持顺序。

#5


0  

As I cant deduct, you need to preserve insertion order, that compleating what @Maroun Maroun wrote, use set, but specialidez implementation like LinkedHashSet<E> whitch does exactly the thing you need.

由于我不能推断,您需要保持插入顺序,即完成@Maroun Maroun Maroun Maroun写的,使用set,但是特殊类型的实现,如LinkedHashSet whitch,完全符合您的需要。

#6


0  

Iterate through array (via iterator, not foreach) and remove duplicates. Use set for find duplicates.

遍历数组(通过迭代器,而不是foreach)并删除重复。使用set查找副本。

OR

Iterate through array and add all elements to LinkedHashSet, it isn't allows duplicates and keeps order of elements. Then clear array, iterate through set and add each element to array.

遍历数组并将所有元素添加到LinkedHashSet中,它不允许重复和保存元素的顺序。然后清除数组,遍历set并将每个元素添加到数组中。

#7


0  

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

虽然将ArrayList转换为HashSet有效地删除了重复,但是如果需要保持插入顺序,我建议您使用这个变体

// list is some List of Strings

// list是一些字符串列表

   Set<String> s = new LinkedHashSet<String>(list);

Then, if you need to get back a List reference, you can use again the conversion constructor.

然后,如果需要返回一个列表引用,可以再次使用转换构造函数。

#8


0  

There are 2 ways:

有两种方法:

  1. create new list with unique ints only

    只创建具有唯一ints的新列表

    • (the same as Maroun Maroun answer)
    • (同Maroun Maroun Maroun应答)
    • you can do it with 2 nested fors like this O(n.n/2):

      你可以用两个嵌套的fors来做这个O(n /2):

      List<int> src,dst;
      // src is input list
      // dst is output list
      dst.allocate(src.num); // prepare size to avoid slowdowns by reallocations
      dst.num=0;             // start from empty list
      for (int i=0;i<src.num;i++)
       {
       int e=1;
       for (int j=0;i<dst.num;i++)
        if (src[i]==dst[j]) { e=0; break; }
       if (e) dst.add(src[i]);
       }
      
  2. You can select duplicate items and delete them ... O(2.n) with the flagged delete

    你可以选择重复的项目并删除它们……O(2.n)带有标记的删除

    • this is way much faster but you need memory table for whole int range
    • 这要快得多,但是整个int范围都需要内存表
    • if you use numbers <0,10000> then it will take BYTE cnt[10001]
    • 如果你使用数字<0,10000>那么它将使用字节cnt[10001]
    • if you use numbers <-10000,10000> then it will take BYTE cnt[20002]
    • 如果你使用数字<-10000,10000>那么它将使用字节cnt[20002]
    • for small ranges like this is ok but if you have to use 32 bit range it will take 4GB !!!
    • 对于像这样的小范围是可以的,但如果你必须使用32位范围,它将需要4GB !!
    • with bit packing you can have 2 bits per value so it will be just 1GB but that is still too much for my taste
    • 对于位包装,每个值可以有2位,所以只有1GB,但对我的口味来说还是太多了
    • ok now how to check for duplicity ...

      好了,现在如何检查口是心非……

      List<WORD> src;  // src is input list
      BYTE cnt[65536]; // count usage for all used numbers
      int i;
      for (i=0;i<65536;i++) cnt[i]=0; // clear the count for all numbers
      for (i=0;i<src.num;i++)         // compute the count for used numbers in the list  
       if (cnt[src[i]]!=255) 
        cnt[src[i]]++;
      
    • after this any number i is duplicate if (cnt[i]>1)
    • 在此之后,任何i都是重复的if (cnt[i]>1)
    • so now we want to delete duplicate items (all except one)
    • 现在我们要删除重复的项目(除了一个)
    • to do that change cnt[] like this

      像这样改变cnt[]。

      for (i=0;i<65536;i++) if (cnt[i]>1) cnt[i]=1; else cnt[i]=0;
      
    • ok now comes the delete part:

      好的,现在是删除部分:

      for (i=0;i<src.num;i++)         
       if (cnt[src[i]]==1) cnt[src[i]]=2; // do not delete the first time
        else if (cnt[src[i]]==2)          // but all the others yes
         { 
         src.del(i);
         i--;                             // indexes in src changed after delete so recheck for the same index again
         }
      
  3. you can combine both approaches together

    您可以将这两种方法结合在一起

  4. delete item from list is slow because of item shift in the list
    • but can be speed up by adding delete flag to items
    • 但是可以通过向项目添加删除标志来加快速度
    • instead of delete just set the flag
    • 与其删除,不如设置标志
    • and after all items to delete is flagged then simply remove hem at once O(n)
    • 在所有要删除的项被标记后,然后立即删除哼哼O(n)
  5. 从列表中删除项由于列表中的项转移而变慢,但是可以通过增加删除标志而不是删除来加快速度只需设置标记,在所有要删除的项被标记后然后立即删除哼哼O(n)

PS. Sorry for non standard list usage but i think the code is understandable enough if not comment me and i respond

PS.不好意思使用了不标准的列表,但是我认为如果不评论我的话代码是可以理解的,我会回复

PPS. for use with signed values do not forget to shift the address by half range !!!

pp。对于带符号值的使用,不要忘记将地址移动一半范围!!!

#9


0  

Below I have given the sample example that implements a generic function to remove duplicate from arraylist and maintain the order at the same time.

下面我给出了一个示例示例,该示例实现了一个通用函数,用于从arraylist中删除副本并同时维护订单。

import java.util.*;
public class Main {
    //Generic function to remove duplicates in list and maintain order
    private static <E> List<E> removeDuplicate(List<E> list) {
        Set<E> array = new LinkedHashSet<E>();
        array.addAll(list);
        return new ArrayList<>(array);
    }
    public static void main(String[] args) {
        //Print [2, 3, 5, 4]
        System.out.println(removeDuplicate(Arrays.asList(2,2,3,5, 3, 4)));
        //Print [AB, BC, CD]
        System.out.println(removeDuplicate(Arrays.asList("AB","BC","CD","AB")));
    }
}

#10


0  

Method 1 : In Python => Using a set and list comprehension

方法1:在Python中使用集合和列表理解

a= [139, 127, 127, 139, 130]

print(a)
seen =set()
aa = [ch  for ch in a if ch not in seen and not seen.add(ch)]
print(aa)

Method 2 :

方法2:

aa = list(set(a))
print(aa)

In Java : using Set and making a new ArrayList

在Java中:使用Set并创建一个新的ArrayList

class t1 {
    public static void main(String[] args) {

int[] a = {139, 127, 127, 139, 130};
List<Integer> list1 = new ArrayList<>();

Set<Integer> set = new LinkedHashSet<Integer>();
for( int ch  : a) {
    if(!set.contains(ch)) {
        set.add(ch);
    }


}//for
set.forEach( (k) -> list1.add(k));
System.out.println(list1);

}
    }

#1


18  

Use an instance of java.util.LinkedHashSet.

使用一个java.util.LinkedHashSet实例。

Set<Integer> set = new LinkedHashSet<>(list);

#2


3  

Construct Set from your list - "A collection that contains no duplicate elements":

从您的列表中构建集合—“不包含重复元素的集合”:

Set<Integer> yourSet = new HashSet<Integer>(yourList);

And convert it back to whatever you want.

然后把它转换成你想要的。

Note: If you want to preserve order, use LinkedHashSet instead.

注意:如果您想保持顺序,请使用LinkedHashSet代替。

#3


2  

With this one-liner:

与这一行程序:

yourList = new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList))

#4


0  

Use LinkedHashSet to remove duplicate and maintain order.

使用LinkedHashSet删除重复并保持顺序。

#5


0  

As I cant deduct, you need to preserve insertion order, that compleating what @Maroun Maroun wrote, use set, but specialidez implementation like LinkedHashSet<E> whitch does exactly the thing you need.

由于我不能推断,您需要保持插入顺序,即完成@Maroun Maroun Maroun Maroun写的,使用set,但是特殊类型的实现,如LinkedHashSet whitch,完全符合您的需要。

#6


0  

Iterate through array (via iterator, not foreach) and remove duplicates. Use set for find duplicates.

遍历数组(通过迭代器,而不是foreach)并删除重复。使用set查找副本。

OR

Iterate through array and add all elements to LinkedHashSet, it isn't allows duplicates and keeps order of elements. Then clear array, iterate through set and add each element to array.

遍历数组并将所有元素添加到LinkedHashSet中,它不允许重复和保存元素的顺序。然后清除数组,遍历set并将每个元素添加到数组中。

#7


0  

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

虽然将ArrayList转换为HashSet有效地删除了重复,但是如果需要保持插入顺序,我建议您使用这个变体

// list is some List of Strings

// list是一些字符串列表

   Set<String> s = new LinkedHashSet<String>(list);

Then, if you need to get back a List reference, you can use again the conversion constructor.

然后,如果需要返回一个列表引用,可以再次使用转换构造函数。

#8


0  

There are 2 ways:

有两种方法:

  1. create new list with unique ints only

    只创建具有唯一ints的新列表

    • (the same as Maroun Maroun answer)
    • (同Maroun Maroun Maroun应答)
    • you can do it with 2 nested fors like this O(n.n/2):

      你可以用两个嵌套的fors来做这个O(n /2):

      List<int> src,dst;
      // src is input list
      // dst is output list
      dst.allocate(src.num); // prepare size to avoid slowdowns by reallocations
      dst.num=0;             // start from empty list
      for (int i=0;i<src.num;i++)
       {
       int e=1;
       for (int j=0;i<dst.num;i++)
        if (src[i]==dst[j]) { e=0; break; }
       if (e) dst.add(src[i]);
       }
      
  2. You can select duplicate items and delete them ... O(2.n) with the flagged delete

    你可以选择重复的项目并删除它们……O(2.n)带有标记的删除

    • this is way much faster but you need memory table for whole int range
    • 这要快得多,但是整个int范围都需要内存表
    • if you use numbers <0,10000> then it will take BYTE cnt[10001]
    • 如果你使用数字<0,10000>那么它将使用字节cnt[10001]
    • if you use numbers <-10000,10000> then it will take BYTE cnt[20002]
    • 如果你使用数字<-10000,10000>那么它将使用字节cnt[20002]
    • for small ranges like this is ok but if you have to use 32 bit range it will take 4GB !!!
    • 对于像这样的小范围是可以的,但如果你必须使用32位范围,它将需要4GB !!
    • with bit packing you can have 2 bits per value so it will be just 1GB but that is still too much for my taste
    • 对于位包装,每个值可以有2位,所以只有1GB,但对我的口味来说还是太多了
    • ok now how to check for duplicity ...

      好了,现在如何检查口是心非……

      List<WORD> src;  // src is input list
      BYTE cnt[65536]; // count usage for all used numbers
      int i;
      for (i=0;i<65536;i++) cnt[i]=0; // clear the count for all numbers
      for (i=0;i<src.num;i++)         // compute the count for used numbers in the list  
       if (cnt[src[i]]!=255) 
        cnt[src[i]]++;
      
    • after this any number i is duplicate if (cnt[i]>1)
    • 在此之后,任何i都是重复的if (cnt[i]>1)
    • so now we want to delete duplicate items (all except one)
    • 现在我们要删除重复的项目(除了一个)
    • to do that change cnt[] like this

      像这样改变cnt[]。

      for (i=0;i<65536;i++) if (cnt[i]>1) cnt[i]=1; else cnt[i]=0;
      
    • ok now comes the delete part:

      好的,现在是删除部分:

      for (i=0;i<src.num;i++)         
       if (cnt[src[i]]==1) cnt[src[i]]=2; // do not delete the first time
        else if (cnt[src[i]]==2)          // but all the others yes
         { 
         src.del(i);
         i--;                             // indexes in src changed after delete so recheck for the same index again
         }
      
  3. you can combine both approaches together

    您可以将这两种方法结合在一起

  4. delete item from list is slow because of item shift in the list
    • but can be speed up by adding delete flag to items
    • 但是可以通过向项目添加删除标志来加快速度
    • instead of delete just set the flag
    • 与其删除,不如设置标志
    • and after all items to delete is flagged then simply remove hem at once O(n)
    • 在所有要删除的项被标记后,然后立即删除哼哼O(n)
  5. 从列表中删除项由于列表中的项转移而变慢,但是可以通过增加删除标志而不是删除来加快速度只需设置标记,在所有要删除的项被标记后然后立即删除哼哼O(n)

PS. Sorry for non standard list usage but i think the code is understandable enough if not comment me and i respond

PS.不好意思使用了不标准的列表,但是我认为如果不评论我的话代码是可以理解的,我会回复

PPS. for use with signed values do not forget to shift the address by half range !!!

pp。对于带符号值的使用,不要忘记将地址移动一半范围!!!

#9


0  

Below I have given the sample example that implements a generic function to remove duplicate from arraylist and maintain the order at the same time.

下面我给出了一个示例示例,该示例实现了一个通用函数,用于从arraylist中删除副本并同时维护订单。

import java.util.*;
public class Main {
    //Generic function to remove duplicates in list and maintain order
    private static <E> List<E> removeDuplicate(List<E> list) {
        Set<E> array = new LinkedHashSet<E>();
        array.addAll(list);
        return new ArrayList<>(array);
    }
    public static void main(String[] args) {
        //Print [2, 3, 5, 4]
        System.out.println(removeDuplicate(Arrays.asList(2,2,3,5, 3, 4)));
        //Print [AB, BC, CD]
        System.out.println(removeDuplicate(Arrays.asList("AB","BC","CD","AB")));
    }
}

#10


0  

Method 1 : In Python => Using a set and list comprehension

方法1:在Python中使用集合和列表理解

a= [139, 127, 127, 139, 130]

print(a)
seen =set()
aa = [ch  for ch in a if ch not in seen and not seen.add(ch)]
print(aa)

Method 2 :

方法2:

aa = list(set(a))
print(aa)

In Java : using Set and making a new ArrayList

在Java中:使用Set并创建一个新的ArrayList

class t1 {
    public static void main(String[] args) {

int[] a = {139, 127, 127, 139, 130};
List<Integer> list1 = new ArrayList<>();

Set<Integer> set = new LinkedHashSet<Integer>();
for( int ch  : a) {
    if(!set.contains(ch)) {
        set.add(ch);
    }


}//for
set.forEach( (k) -> list1.add(k));
System.out.println(list1);

}
    }