3

我正在尝试为我的 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;

如果有人可以解释我做错了什么以及我应该如何去做,那将非常有帮助。请注意,由于这是为我准备测试,我希望得到解释,而不仅仅是正确的代码。

4

10 回答 10

5

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

正确解决方案的提示:

  1. 您将需要使用多个迭代器...
  2. 您没有将任何内容放入要返回的列表中。
  3. 您需要确定是创建和返回一个新列表,还是从现有列表中删除元素。两者都做没有意义。

将来,当您提出问题时,您应该更好地说明程序实际上应该做什么。例如:

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

在决定如何解决这样的问题时,所有这些事情都很重要。尤其是在现实世界中。即使你的作业没有说明这些事情,你仍然需要自己决定你的代码是如何工作的……并用 javadoc 注释记录下来。

于 2013-03-03T01:24:21.277 回答
3
  • i==0你的iterator.next()get(i)将是相同的元素时,所以你只是删除了它。
  • 对于同一个列表,最好不要iterator.remove()for循环中执行。
  • 你对 没有add任何东西newList,只是简单地退回了它
  • 对此作业的建议:

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

我的 2 美分

于 2013-03-03T01:28:47.317 回答
2

以下是解决方案:

    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;
    }
于 2018-08-12T04:27:37.827 回答
1

遍历列表并删除元素会更改列表...如果您查看元素“4”并决定删除它,您查看的下一个元素是什么?提示:不是原来的元素“5”而是新的元素“5”……

于 2013-03-03T01:23:57.213 回答
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());
        }
    }

}
于 2018-02-08T15:07:55.687 回答
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 的答案中复制的。

于 2013-03-19T07:30:29.920 回答
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);
    }

}
于 2013-03-19T06:56:43.053 回答
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" 
于 2013-12-20T11:09:14.480 回答
0

我已经为每个都使用了高级,并且还尝试通过转换ArrayListHashSet和再次转换为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());

}
于 2017-04-03T19:05:13.597 回答
-1

假设ArrayListimplements ListADTArrayListArrayListIterator类按预期实现,这BadListException是一个带有零参数构造函数的未经检查的异常。还假设不能将空元素添加到列表中。

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

  1. 必须显式使用迭代器来遍历列表(即,您不能使用 for 循环或 Java 的扩展 for 循环)
  2. 不得使用该contains方法
  3. 可以使用在线阅读中描述的任何ListADT方法(除了),包括,但不得使用在线阅读中未提及的任何其他方法containsListADT.iterator()List
  4. 不得修改参数的内容。

函数的骨架:

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在线阅读中描述的接口中的方法(包括迭代器方法,如上所述)。

我怎样才能做到这一点?

于 2016-06-18T22:53:32.280 回答