使用迭代器从Java中的List中删除重复项

时间:2013-03-03 01:18:01

标签: java arraylist duplicate-removal

我正在尝试处理我的简介java课程的作业问题,我们应该在不使用集合或.contains()方法的情况下从列表中删除重复项目。基本上只使用迭代器和.equals()方法。我的代码如下:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class sample {
public static void main(String[] args) throws BadListException {
    List<String> myList = new ArrayList<String>();
    myList.add("A");
    myList.add("B");
    myList.add("B");
    myList.add("C");
    myList.add("B");
    myList.add("D");


    unique(myList);
    System.out.println(myList);


}
public static List<String> unique( List<String> items ) throws BadListException { 

    List<String> newList = new ArrayList<String>();
    Iterator<String> itr = items.listIterator();

    // If items is null, throw a BadListException. 

    if (items == null){
        throw new BadListException();
    }
    // If items is empty, return a new empty list. 

    if (items.isEmpty()){
        return newList;
    }

    // Otherwise create and return a new list that contains the items 
    // in L with all duplicates removed.  
    // Example: items: "A","B","C"              result: "A","B","C" 
    // Example: items: "A","A","A"              result: "A" 
    // Example: items: "A","B","B","C","A","D"  result: "A","B","C","D" 

    while (itr.hasNext()){
        for (int i = 0; i < items.size()-1; i++){
            if (itr.next().equals(items.get(i))){
                itr.remove();
            }
        }

    }
    items = newList;
    return newList;

如果有人能够解释我做错了什么以及我该如何去做,那将会非常有帮助。请注意,由于这是为了让我为测试做好准备,我将非常感谢您的解释,而不仅仅是正确的代码。

10 个答案:

答案 0 :(得分:4)

我建议您使用调试器来查看程序当前正在执行的操作,而不是准确地解释出现了什么问题。特别是,每次调用iter.next()时,请查看迭代器返回的内容。

提供正确解决方案的提示:

  1. 您将需要使用多个迭代器......
  2. 您没有在要返回的列表中添加任何内容。
  3. 您需要记住是创建和返回新列表,还是从现有列表中删除元素。做两件事没有意义。

  4. 将来,当您提出问题时,您应该更好地说明该计划实际应该做什么。例如:

    • 您没有说明unique方法是否应该从参数列表中删除元素或返回包含(仅)唯一元素的新列表。
    • 您没有说明列表中元素的顺序是否重要。
    • 您没有说是否可以更改输入列表....

    所有这些事情在决定如何解决这样的问题时都很重要。特别是在现实世界中。即使你的任务没有陈述这些内容,你仍然需要自己决定你的代码是如何工作的......并用javadoc注释来记录它。

答案 1 :(得分:3)

  • i==0 iterator.next()get(i)成为同一元素时,您只需删除它。
  • 对于相同的列表,最好不要在iterator.remove()循环中执行for
  • add没有newList任何内容,只返回
  • 对此作业的建议:

你可以先排序列表,然后通过它,如果一个元素等于它的前一个元素,则删除该元素。当然,如果需要,您可以创建一个新列表来保存这些独特元素。

我的2美分

答案 2 :(得分:1)

迭代列表并删除元素会更改列表...如果你看了元素&#34; 4&#34;并决定删除它,你看下一个元素是什么?提示:它不是原始元素&#34; 5&#34;但新元素“5”...

答案 3 :(得分:1)

您可以创建自己的迭代器,其目的是仅返回一次重复的值。

public class NoDuplicatesIterator<T> implements Iterator<T> {

    private final List<T> array;
    private final List<T> encountered;
    private int index = 0;

    public NoDuplicatesIterator(List<T> array) {
        this.array = array;
        encountered = new ArrayList<>();
    }

    @Override
    public boolean hasNext() {
        if (index > array.size() - 1) {
            return false;
        }

        while (encountered.contains(array.get(index)) && index < array.size() - 1) {
            index++;
        }

        return index <= array.size() - 1;
    }

    @Override
    public T next() {
        encountered.add(array.get(index));
        return array.get(index++);
    }

}

用法:

public class Main {

    public static void main(String[] args) {
        List<Integer> array = Arrays.asList(new Integer[]{100, 2, 2, 1, 1, 2, 3, 3, 15, 4, 4, 5, 6, 7, 7, 8, 99, 99, 100, 99, 2, 77, 23, 14, 2, 15});
        NoDuplicatesIterator<Integer> it = new NoDuplicatesIterator(array);

        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }

}

答案 4 :(得分:0)

code extract without using iterator 

import java.util.ArrayList;
import java.util.List;

  public class Test {
    final static List<String> str = new ArrayList<String>();
    public Test(){

        str.add("A");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("D");
        str.add("A");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("D");
        str.add("B");
        str.add("C");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("D");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("C");
        str.add("D");
        System.out.println(str);


    }

    public  List<String> rmovedDuplicate(List<String> str){

        List<String> finalList = new ArrayList<String>();

        for(int i =0; i<str.size();i++){
            for (int j=i+1; j<str.size();j++){
                if(str.get(i).equals(str.get(j))){
                    str.remove(j);
                    i=0;

                }
            }
        }

        System.out.println("final list :"+str);
        return str;
    }

    public static void main(String args[]){
        Test t = new Test();
        t.rmovedDuplicate(str);
    }

}

答案 5 :(得分:0)

另一种简单的方法如下。

import java.util.HashSet;
import java.util.List;
import java.util.Set;public class Main {

    /**
     * @param args
     */
    public static void main(String args[]) throws SQLException {
        System.out.println("Entered Main");
        Test();
        System.out.println(str);
        set.addAll(str);
        System.out.println(set);
        str.clear();
        str.addAll(set);
        System.out.println(str);
    }
    final static List<String> str = new ArrayList<String>();
    final static Set<String> set = new HashSet<String>();
    public static void Test(){

        str.add("A");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("D");
        str.add("A");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("D");
        str.add("B");
        str.add("C");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("D");
        str.add("B");
        str.add("C");
        str.add("C");
        str.add("C");
        str.add("D");
        System.out.println(str);
    }

填写列表的测试方法是从Vidyarani Shinde的答案中复制的。

答案 6 :(得分:0)

非常简单

way is ..first to check the list has that value if so ,skip adding it if not add the element and u get your unique list...instead of running intensive Iterator operation :)

Example

List<Integer> listOfUserIds = new ArrayList<Integer>();
     Integer UserIdCheck = 0;
     for (User userTest : userCollection) {
     UserIdCheck = userService.getUserByRegionCode(userTest.                      .getRegionId());
    if (!listOfUserIds.contains(UserIdCheck)) //check befor adding listOfUserIds.add(UserIdCheck);
        }
  } 
  return listOfUserIds.toString().replace("[", "").replace("]", ""); // if u like can remove [ and ] from the list and simply return a string like "4,5,6" 

答案 7 :(得分:0)

我已经使用了两个版本的高级版本,并尝试将ArrayList转换为HashSet并再次转换为ArrayList。两种解决方案都可以正常工作你可以选择任何一个

public static void main(String[] args) {
    ArrayList<String> wordDulicate = new ArrayList<String>();

    wordDulicate.add("Tom");
    wordDulicate.add("Jones");
    wordDulicate.add("Sam");
    wordDulicate.add("Jamie");
    wordDulicate.add("Robie");
    wordDulicate.add("Helen");
    wordDulicate.add("Helen");
    wordDulicate.add("Helen");
    wordDulicate.add("Helen");
    wordDulicate.add("Tom");
    wordDulicate.add("Troy");
    wordDulicate.add("Mika");
    wordDulicate.add("Tom");

    System.out.println("Array List size"+wordDulicate.size());

    ArrayList<String> nonDuplicat=new ArrayList<String>(new HashSet<String>(wordDulicate));

    System.out.println("Array List size"+nonDuplicat.size());
    ArrayList<String> nonDuplicatThroughIterator=new ArrayList<String>();

    for(String each:wordDulicate){
        if(!nonDuplicatThroughIterator.contains(each))
            nonDuplicatThroughIterator.add(each);
    }
    System.out.println("Array List size"+nonDuplicatThroughIterator.size());

}

答案 8 :(得分:0)

下面是解决方法:

    List<String> list = Lists.newArrayList("1","4","8","1","4","5","1");
    Collections.sort(list);

    Iterator<String> itr = list.iterator();
    String old = itr.next();
    while(itr.hasNext())
    {
        String next = itr.next();

        if(old.equals(next))
        {
            itr.remove();
        }
        old = next;
    }

答案 9 :(得分:-1)

假设ArrayList实现ListADTArrayListArrayListIterator类按预期实现,BadListException是未经检查的异常,为零-argument构造函数。假设也可以不将null元素添加到列表中。

我必须完成下面指定的Java方法,使用迭代器。我的解决方案应该满足这些要求:

  1. 必须显式地使用迭代器遍历列表(即,您可能不使用for循环或Java的扩展for循环)
  2. 不得使用contains方法
  3. 可以使用on-line reading,中包含ListADT所述的任何contains方法(ListADT.iterator()除外),但不得使用此处未提及的任何其他List方法
  4. 不得修改参数的内容。
  5. 功能的骨架:

    public static ListADT<String> union(ListADT<String> list1, ListADT<String> list2) {
        // If list1 or list2 (or both list1 and list2) is null, throw a BadListException. 
        // If list1 and list2 are both empty, return a new empty list.
        // If list1 is empty (but not list2), return a new list containing the strings in
        //     list2 with all duplicates removed.
        // If list2 is empty (but not list1), return a new list containing the strings in
        //     list1 with all duplicates removed.
        // Otherwise, create and return a new list that contains the strings in list1 and
        //     the strings in list2 with all duplicates removed.
        //
        // Examples:
        //  list1: "a","b","c"          list2: "d","e","f"      result: "a","b","c","d","e","f"
        //  list1: "a","c","b","d"      list2: "e","d","a","f"  result: "a","c","b","d","e","f"
        //  list1: "a","b","c","b","a"  list2: "c","a","b"      result: "a","b","c"
        //
        // Note: the list returned does not need to be in any particular order
    

    我必须确保我的解决方案仅使用在线阅读中描述的ListADT接口中的方法(包括迭代器方法,如上所述)。

    我该怎么做?