List를 구현하는 Set을 보존하는 게재 신청서가 있습니까?


84

나는의 구현을 찾기 위해 노력하고있어 java.util.Listjava.util.Set자바에서 동시에합니다. 이 클래스는 고유 한 요소 ( Set) 만 허용 하고 순서 (예 :)를 유지하기 를 원합니다 List. JDK 6에 존재합니까?

List<T>#add(int, T)특정 위치에 삽입 할 수 있도록하는 것이 중요합니다 .


당신은 그들의 보존 의미합니까 삽입 순서 또는 의해 정의 된 몇 가지 순서를 Comparator? 또한 List인터페이스 의 의미 도 원하십니까?

답변:


207

TreeSet요소 순서로 정렬됩니다. LinkedHashSet게재 신청서를 유지합니다. 그 중 하나가 당신이 추구했던 것입니다.

당신은 당신이에 삽입 할 수하도록 지정한 임의의 위치, 당신이 당신의 자신의 작성해야 의심 - 단지 포함하는 클래스 생성 HashSet<T>과를 ArrayList<T>; 항목을 추가 할 때 목록에 추가하기 전에 세트에 있는지 여부를 확인하십시오.

또한 아파치의 평민 - collections4 제공 ListOrderedSetSetUniqueList유사하게 동작 주어진 요구 사항을 충족해야합니다.



12

당신은 같은 의미 LinkedHashSet입니까? 이렇게하면 항목 순서가 유지되지만 중복은 허용되지 않습니다.

IMHO는 특이한 요구 사항이지만 중복없이 목록을 작성할 수 있습니다.

class SetList<T> extends ArrayList<T> {
    @Override
    public boolean add(T t) {
        return !super.contains(t) && super.add(t);
    }

    @Override
    public void add(int index, T element) {
        if (!super.contains(element)) super.add(index, element);
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            added |= add(t);
        return added;
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> c) {
        boolean added = false;
        for (T t : c)
            if (!super.contains(t)) {
                super.add(index++, t);
                added = true;
            }
        return added;
    }
}

List인터페이스를 구현하지 않습니다 . 질문에 대한 변경 사항을 참조하십시오
yegor256

2
stackoverflow.com/a/8185105/253468O(n)삽입 복잡성 이 없기 때문에 더 좋아 보입니다 O(log(n)). 이중 저장과 삽입 작업 사이에 고려해야 할 절충점이 있습니다.
TWiStErRob

8

당신은 구현할 수 없습니다 ListSet계약 위반하지 않고 한 번에. 예를 들어 Set.hashCode계약 을 참조하십시오 .

집합의 해시 코드는 집합에있는 요소의 해시 코드의 합으로 정의되며, 여기서 null 요소의 해시 코드는 0으로 정의됩니다.

반면에 계약은 List.hashCode다음 과 같습니다.

목록의 해시 코드는 다음 계산의 결과로 정의됩니다.

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

따라서 두 계약이 모두 이행되도록 보장하는 단일 클래스를 구현하는 것은 불가능합니다. equals구현 에도 동일한 문제가 있습니다.



0

비슷한 문제가있어서 직접 작성했습니다. 를 참조하십시오 여기 . 는 IndexedArraySet확장 ArrayList및 구현 Set하므로 필요한 모든 작업을 지원해야합니다. ArrayList다음 요소를 모두 이동해야하므로 큰 목록 의 경우 중간 위치에 요소를 삽입 하면 속도가 느려질 수 있습니다. 나는 IndexedArraySet그것을 바꾸지 않는다.


0

다른 옵션 ( List인터페이스 요구 사항 제외)은 Guava의 ImmutableSet이며 삽입 순서를 유지합니다. 에서 자신의 위키 페이지 :

정렬 된 컬렉션을 제외하고 는 구성 시간부터 순서가 유지됩니다. 예를 들면

ImmutableSet.of("a", "b", "c", "a", "d", "b")

"a", "b", "c", "d"순서로 요소를 반복합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.