2013-08-23 6 views
-5

나는 List of 100000 Objects를 가지고 있습니다. 그리고 그 독특한 목록. 새 객체를 추가하고 싶습니다. 그러나 추가 할 조건은 새 요소가 이미 목록에 있고 목록에 추가해서는 안되며 예외를 throw해야하는 경우 고유 한 의미를 가져야합니다. 아이디어가 있으면 알려주세요.목록에 새 고유 요소를 추가하는 방법

+0

당신은 세트를보아야합니다 - 바람직하게는리스트를 만드십시오 – Mark

+1

'List' 대신'Set' 사용 –

답변

0

당신은 오히려 Set 오히려 List을 사용해야합니다. 당신이 그것을 얻을 수 있지만

는하지만 -

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

세트를 목록으로 변환하는 것은 1 개의 부족한 개체에 대해 큰 성능이됩니다. – Umesh

+0

@Umesh가 사실 일 수 있습니다. 방금 길을 보여 줬어. :) –

0

사용 Set 대신 List를 사용하여 Set을 만들 수 있습니다. 목록을 갖고 싶다면 다음 예제를 고려하십시오. 삽입 순서가 중요한 경우

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

당신은 추가 할 요소가 목록에 이미 있는지 여부를 확인하기 위해 contains를 사용하여, 당신에게 List, 예를 들어, 때문에 주문 사항을 사용하는 좋은 이유가있는 경우 :

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

그러나 10 만 개 개체의 경우 contains은 선형 검색을 수행해야하므로 속도가 느립니다.

목록에 개체가 자연 순서대로 저장되는 경우 (예 : java.util.Comparator으로 설명 된 주문). 이 경우, 대신 contains를 사용하여, 당신은 O를 O (N)에서 검색을 줄이기 위해, 이진 검색을 사용할 수 (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은 정렬 된 트리이므로 해당 옵션이 사용자에게 적합한 지 여부를 평가할 수 있습니다.

마지막으로, 당신은 모두의 모든 요소를 ​​저장, 즉 ListSet을 결합 할 수 있습니다 : 목록 요소의 순서를 유지하면서 세트가 당신에게 빠른 contains을 제공합니다. 이 방법, 당신은 Comparator에 의해 정의 된 특정 순서에 제한되지하고 있지만, 당신은 단순히 삽입의 순서를 사용할 수 있습니다 :이 LinkedHashSet 당신을 위해 무엇을 기본적으로

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

- 베드로 발저의 답변을 참조하십시오.

관련 문제