从ArrayList中删除重复值

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

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

List list = new ArrayList(); 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或其他方式,但只使用数组列表。 我想对此有你的建议。 谢谢你提前回答。

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

 list = new ArrayList(new LinkedHashSet(list)) 

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


编辑对于注释中提到的要求:如果要删除重复元素,但将字符串视为忽略大小写,则可以执行以下操作:

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

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

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

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

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

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

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

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

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

UPDATE

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

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

Java 8 流function

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

 stringList.stream().distinct(); 

从文档中,

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


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

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

从文档中,

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

希望有所帮助。

 List list = new ArrayList(); list.add("Krishna"); list.add("Krishna"); list.add("Kishan"); list.add("Krishn"); list.add("Aryan"); list.add("Harm"); HashSet hs=new HashSet<>(list); System.out.println("=========With Duplicate Element========"); System.out.println(list); System.out.println("=========Removed Duplicate Element========"); System.out.println(hs); 

我不认为list = new ArrayList(new LinkedHashSet(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方法进行了一些更改。

用于从列表中删除重复项的简单function

 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,2,3,1,3,3,2,3,1,2,3,3,4,4,4,1]
输出:[1,2,3,4]

  public List removeDuplicates(List 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; } 

这将是最好的方式

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

最好使用HastSet

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

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

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

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

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

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

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

 public static void main(String[] args) { @SuppressWarnings("serial") List lst = new ArrayList() { @Override public boolean add(Object e) { if(!contains(e)) return super.add(e); else return false; } }; lst.add("ABC"); lst.add("ABC"); lst.add("ABCD"); lst.add("ABCD"); lst.add("ABCE"); System.out.println(lst); } 

这是更好的方法

list = list.stream().distinct().collect(Collectors.toList());
这可能是使用Java8 Stream API的解决方案之一。 希望这可以帮助。

使用java 8:

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

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

 //list is the original arraylist containing the duplicates as well List uniqueList = new ArrayList(); for(int i=0;i 

希望这可以帮助!

 private static void removeDuplicates(List list) { Collections.sort(list); int count = list.size(); for (int i = 0; i < count; i++) { if(i+1 
 public static List removeDuplicateElements(List array){ List temp = new ArrayList(); List count = new ArrayList(); for (int i=0; i0;i--) { array.remove(i); } return array; } }