2013-08-23 77 views
-5

我有一個100000個對象列表。它的獨特名單。我想要添加一個新的對象。但是要添加的條件是它應該是唯一的含義,如果新元素已經在列表中,不應該添加到列表中並且應該拋出異常。請讓我知道是否有想法。如何在列表中添加新的唯一元素

+0

您需要查看集合 - 最好使列表成爲集合 – Mark

+1

使用'Set'而不是'List' –

回答

0

你還是使用SetList

但是,儘管你可以得到它 -

List<Object> list =...; 
public boolean add(Object obj){ 
    Set<Object> set = new HashSet<>(list); 
    return set.add(obj); 
} 
+0

我已經擁有列表對象與我,如果我將列表轉換爲Set,它將花費很多時間。 – Umesh

+0

@ Umesh,任何好的IDE應該能夠輕鬆地重構這個......'List'實際上會在長期運行中造成更多的破壞,所以值得每一分鐘重構。 – rid

+0

我們無法重構它,它對我們的應用程序有很大的改變。 – Umesh

0

您需要使用Set數據結構爲您的要求。但是,如果您嘗試添加新的重複項,它不會引發異常。

如果你已經有名單,那麼你可以使用

Set<YourType> foo = new HashSet<YourType>(yourList); 
+0

將列表轉換爲Set對於1個缺少對象 – Umesh

+0

@ Umesh可能是真的。我只是展示了一種方式:) –

0

使用Set,而不是List創建Set。如果你真的想要一個List,請考慮下面的例子。

List<String> myList=new ArrayList<>(); 
    myList.add("asd"); 
    myList.add("asf"); 
    myList.add("asf"); 
    Set<String> set=new HashSet<>(); 
    set.addAll(myList); 
    set.add("newString"); 
    myList.clear(); 
    myList.addAll(set); 
0

如果插入順序是重要的,使用LinkedHashSet代替,這基本上是一組,但也跟蹤一個列表內的元件,以允許迭代過以相同的順序中的元素,因爲它們插入(與列表)。

至於例外嘗試添加重複的元素時,你可以檢查,如果被驗證添加的元素,該add(..)方法返回true並拋出一個Exception否則,或通過創建一個專門的子類,做這個檢查:

public class UniqueItemList <E> extends LinkedHashSet<E> { 

    @Override 
    public boolean add (E e) { 
     checkContains(e); 
     return super.add(e); 
    }; 

    @Override 
    public boolean addAll (Collection<? extends E> collection) { 
     for (E e : collection) { 
      add(e); 
     } 
     return !collection.isEmpty(); 
    } 

    private void checkContains (E e) { 
     if (contains(e)) { 
      throw new IllegalArgumentException("Element was already added"); 
     } 
    } 
} 
1

如果你有一個很好的理由使用List,例如,因爲爲了事宜你,只是用contains檢查您要添加的元素是否已在列表中:

public void addUnique(Object element) throws NotUniqueException { 
    if (list.contains(element)) { 
     throw new NotUniqueException(list, element); 
    } else { 
     list.add(element); 
    } 
} 

但是,對於100,000個對象,contains會很慢,因爲它必須執行線性搜索。

另一種方法是如果您的列表按照某種自然順序存儲對象,例如,可以用java.util.Comparator來描述的訂單。在這種情況下,而不是使用contains,你可以使用二進制搜索,以減少從O(n)與澳搜索(的log(n)):

public void addUnique(Object element) throws NotUniqueException { 
    int index = Collections.binarySearch(list, element, comparator); 
    if (index >= 0) { 
     throw new NotUniqueException(list, element); 
    } else { 
     list.add(index, element); 
    } 
} 

但是,缺點是您add現在變得更加昂貴,因爲爲了保持列表排序,必須移動一些元素以爲新元素騰出空間。這使得你的add是一個線性操作。

一個數據結構,爲您提供訂單和快速contains和快速add是一個排序樹,所以你可能想要評估這是否是一個選項。

最後,你可以用List結合了Set,即存儲在這兩個的每一個元素:一組爲您提供了快速contains而列表保留元素的順序。通過這種方法,你不僅限於由Comparator定義的順序,但你可以簡單地使用插入的順序:

public void addUnique(Object element) throws NotUniqueException { 
    if (set.contains(element)) { 
     throw new NotUniqueException(list, element); 
    } else { 
     list.add(element); 
     set.add(element); 
    } 
} 

這基本上就是LinkedHashSet爲你做 - 也看到彼得瓦爾澤的答案。