【发布时间】:2013-10-30 23:09:33
【问题描述】:
我有一个数组,比如List<Integer> 139, 127, 127, 139, 130
如何删除重复项并保持其顺序不变?即139, 127, 130
【问题讨论】:
-
手动删除重复,这种情况下可以保持顺序。
标签: java arrays duplicates
我有一个数组,比如List<Integer> 139, 127, 127, 139, 130
如何删除重复项并保持其顺序不变?即139, 127, 130
【问题讨论】:
标签: java arrays duplicates
使用java.util.LinkedHashSet 的实例。
Set<Integer> set = new LinkedHashSet<>(list);
【讨论】:
有了这个单行:
yourList = new ArrayList<Integer>(new LinkedHashSet<Integer>(yourList))
【讨论】:
没有LinkedHashSet 开销(使用HashSet 代替可见元素,这会稍微快一些):
List<Integer> noDuplicates = list
.stream()
.distinct()
.collect(Collectors.toList());
请注意,订单由Stream.distinct() 合约保证:
对于有序流,不同元素的选择是稳定的(对于 重复元素,该元素首先出现在遭遇战中 顺序被保留。)
【讨论】:
从您的列表中构造Set - “一个不包含重复元素的集合”:
Set<Integer> yourSet = new HashSet<Integer>(yourList);
并将其转换回您想要的任何内容。
注意:如果要保持顺序,请改用LinkedHashSet。
【讨论】:
LinkedHashSet 来保留插入顺序。
使用LinkedHashSet 删除重复并保持秩序。
【讨论】:
正如我无法推断的那样,您需要保留插入顺序,即完成 @Maroun Maroun 所写的内容,使用 set,但像 LinkedHashSet<E> whitch 这样的特殊实现完全可以满足您的需求。
【讨论】:
遍历数组(通过迭代器,而不是 foreach)并删除重复项。使用 set 查找重复项。
或
遍历数组并将所有元素添加到LinkedHashSet,它不允许重复并保持元素的顺序。 然后清空数组,遍历集合并将每个元素添加到数组中。
【讨论】:
虽然将 ArrayList 转换为 HashSet 可以有效地删除重复项,但如果您需要保留插入顺序,我还是建议您使用此变体
// list 是一些字符串列表
Set<String> s = new LinkedHashSet<String>(list);
然后,如果需要取回 List 引用,可以再次使用转换构造函数。
【讨论】:
有两种方式:
只创建具有唯一整数的新列表
你可以用 2 个嵌套的 fors 来做到这一点,像这样 O(n.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]);
}
您可以选择重复的项目并将其删除... O(2.n) 带有标记的删除
现在如何检查重复性...
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]]++;
像这样改变cnt[]
for (i=0;i<65536;i++) if (cnt[i]>1) cnt[i]=1; else cnt[i]=0;
好的,现在是删除部分:
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
}
您可以将这两种方法结合在一起
PS。很抱歉使用非标准列表,但我认为如果不评论我,我认为代码是可以理解的,我会回复
PPS。对于有符号值,不要忘记将地址移动一半!!!
【讨论】:
下面我给出了示例示例,该示例实现了一个通用函数以从 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")));
}
}
【讨论】:
方法 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)
方法二:
aa = list(set(a))
print(aa)
在 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);
}
}
【讨论】: