从ArrayLists中删除重复项

我有一个自定义对象的ArrayList。 我想删除重复的条目。

对象有三个字段: title, subtitleid 。 如果一个字幕多次出现,我只需要第一个带有那个副标题的项目(忽略带有该副标题的剩余对象)。

您可以使用自定义Comparator将ArrayList的内容放在TreeSet中,如果两个字幕相同,则应返回0。 之后,您可以转换列表中的Set并使列表没有“重复”。 这是Object的一个例子,当然你应该使用正确的类和逻辑。

 public void removeDuplicates(List l) { // ... the list is already populated Set s = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { // ... compare the two object according to your requirements return 0; } }); s.addAll(l); List res = Arrays.asList(s.toArray()); } 
 List list = (...); //list may contain duplicates. //remove duplicates if any Set setItems = new LinkedHashSet(list); list.clear(); list.addAll(setItems); 

您可能需要覆盖“equals()”,以便如果2个元素具有相同的字幕(或者可能是tite和subtitle),则认为它们是等于的

我建议使用Set

http://download.oracle.com/javase/6/docs/api/java/util/Set.html

其本质上不能包含重复的项目。 您可以使用原始ArrayList创建新集

 Set myset = new HashSet(myArrayList); 

或者,只需从头开始使用Set,不要使用ArrayList,因为它没有执行您需要的function。

 List result = new ArrayList(); Set titles = new HashSet(); for( Item item : originalList ) { if( titles.add( item.getTitle() ) { result.add( item ); } } 

如果元素已经存在,则Set add()返回false

您可以使用O(n ^ 2)解决方案:使用list.iterator()迭代列表一次,并在每次迭代时再次迭代它以检查是否存在重复。 如果有 – 调用iterator.remove() 。 其中一个变体是使用guava的Iterables.filter(list, predicate) ,其中过滤逻辑位于谓词中。

另一种方式(可能更好)是定义equals(..)hashCode(..)方法来处理自定义相等逻辑,然后简单地构造一个new HashSet(list) 。 这将清除重复。

如果我理解正确你有一个ArrayList ,我们称之为list 。 你的Custom类有一个字幕字段,比方说getSubtitle()方法返回String 。 您只想保留第一个唯一的字幕并删除任何剩余的副本。 这是你如何做到这一点:

 Set subtitles = new HashSet(); for (Iterator it = list.iterator(); it.hasNext(); ) { if (!subtitles.add(it.next().getSubtitle())) { it.remove(); } } 

删除集合中的任何重复项,同时保留订单(如果它是有序集合)。 对大多数情况来说足够有效。

 public static > T removeDuplicates(T collection) { Set setItems = new LinkedHashSet(collection); collection.clear(); collection.addAll(setItems); return collection; } 

使用Collections.sort()排序并使用一个简单的循环来捕获双精度数,例如:

 Collections.sort(myList); A previous = null; for (A elem: myList) { if (elem.compareTo(previous) == 0) continue; previous = elem; [... process unique element ...] } 

这假设您将在类型A中实现Comparable。

Java8更新:

使用Java8流你也可以非常简单。

 ArrayList deduped; deduped = yourArrayList.stream() .distinct() .collect(Collectors.toCollection(ArrayList::new)); 

这也比保持排序的ArrayListSetArrayList更有优势。

 private static List removeDuplicates(List list) { ArrayList uniqueList = new ArrayList(); for (Integer i : list) { if (!inArray(i, uniqueList)) { uniqueList.add(i); } } return uniqueList; } private static boolean inArray(Integer i, List list) { for (Integer integer : list) { if (integer == i) { return true; } } return false; } 
  List all = ********//this is the object that you have already and filled it. List noRepeat= new ArrayList(); for (YourObject al: all) { boolean isPresent = false; // check if the current objects subtitle already exists in noRepeat for (YourObject nr : noRepeat) { if (nr.getName().equals(al.getName()) { isFound = true;//yes we have already break; } } if (!isPresent) noRepeat.add(al);//we are adding if we don't have already } 

获取一个相同类型的新ArrayList对象
逐个将所有旧的arraylists元素添加到这个新的arraylist对象中

但在添加每个对象之前,请检查新的arraylist,如果有任何对象具有相同的副标题。如果新的arraylist包含这样的副标题,请不要添加它。 否则添加它

解决方案取决于具体情况。

如果您没有太多数据,那么请使用Set Set unique = new HashSet<>(yourList); (如果你关心订单,请使用LinkedHashSet。它会创建一个新的集合,但通常不是问题。

如果要修改现有列表并且不想/不能创建新集合,可以删除重复项,如下所示:

 List numbers = new ArrayList<>(asList(1, 1, 2, 1, 2, 3, 5)); System.out.println("Numbers: " + numbers); ListIterator it = numbers.listIterator(); while (it.hasNext()) { int i = it.nextIndex(); Integer current = it.next(); for (int j = 0; j < i; ++j) { if (current.equals(numbers.get(j))) { it.remove(); break; } } } System.out.println("Unique: " + numbers); 

它工作在O(n ^ 2),但它的工作原理。 类似的实现,但更简单,是列表排序 - 在O(n)时间工作。 这两种实现都在Farenda中进行了解释: 从列表中删除重复项 - 各种实现 。

使用Java8流的另一种方法你也可以做得很酷。

列出CustomerLists;

List unique = CustomerLists.stream()。collect(collectingAndThen(toCollection(() – > new TreeSet <>(comparisonLong(Customer :: getId))),ArrayList :: new));

在Java 8中,您还可以执行以下操作:

 yourList.stream().collect( Collectors.toMap( obj -> obj.getSubtitle(), Function.identity(), (o1,o2) -> o1) .values(); 

诀窍是收集流映射并提供关键的碰撞解析器lambda( (o1,o2) -> o1 ),它始终返回其第一个参数。 结果是Collection,而不是List,但您可以轻松地将其转换为List:

 new ArrayList(resultCollection);