簡體   English   中英

使用迭代器從Java中的List中刪除重復項

[英]Removing duplicates from a List in Java using iterators

我正在嘗試為我的簡介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;

如果有人能夠解釋我做錯了什么以及我應該如何去做,那將是非常有幫助的。 請注意,由於這是為了讓我為測試做好准備,我希望得到解釋,而不僅僅是正確的代碼。

我將建議您使用調試器來查看程序當前正在執行的操作,而不是准確地解釋出現了什么問題。 特別是,每次調用iter.next()時,請查看迭代器返回的內容。

提示正確的解決方案:

  1. 您將需要使用多個迭代器...
  2. 您沒有將任何內容放入要返回的列表中。
  3. 您需要記住是創建和返回新列表,還是從現有列表中刪除元素。 做兩件事沒有意義。

將來,當您提出問題時,您應該更好地說明該計划實際應該做什么。 例如:

  • 您沒有說明該unique方法是否應該從參數列表中刪除元素或返回包含(僅)唯一元素的新列表。
  • 您沒有說明列表中元素的順序是否重要。
  • 您沒有說是否可以更改輸入列表....

所有這些事情在決定如何解決這樣的問題時都很重要。 特別是在現實世界中。 即使你的任務沒有陳述這些內容,你仍然需要自己決定你的代碼是如何工作的......並用javadoc注釋來記錄它。

  • i==0你的iterator.next()get(i)將是相同的元素,所以你只是刪除它。
  • 對於相同的列表,最好不要在for循環中執行iterator.remove()
  • 你沒有向newList add任何東西,只是簡單地返回它
  • 對此作業的建議:

你可以先列表進行排序 ,然后通過它,如果一個元素等於它的前一個元素,則刪除該元素。 當然,如果需要,您可以創建一個新列表來保存這些獨特元素。

我的2美分

迭代列表並刪除元素會更改列表...如果您查看元素“4”並決定將其刪除,那么您要查看的下一個元素是什么? 提示:它不是原始元素“5”,而是新元素“5”......

您可以創建自己的迭代器,其目的是僅返回一次重復的值。

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());
        }
    }

}

以下是解決方案:

    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;
    }
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);
    }

}

另一種簡單的方法如下。

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的答案中復制的。

很簡單

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" 

我已經為每個使用了兩個高級版本,並且還嘗試將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());

}

假設ArrayList實現ListADTArrayListArrayListIterator類按預期實現,並且BadListException是帶有零參數構造函數的未經檢查的異常。 還假設可以不將null元素添加到列表中。

我必須完成下面指定的Java方法,使用迭代器。 我的解決方案應滿足以下要求:

  1. 必須顯式使用迭代器遍歷列表(即,您可能不使用for循環或Java的擴展for循環)
  2. 不得使用contains方法
  3. 可以使用在線閱讀中描述的任何ListADT方法( contains除外) 包括ListADT.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接口中的方法(包括迭代器方法,如上所述)。

我怎樣才能做到這一點?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM