문제

나는 알고있다 SortedSet,하지만 내 경우에는 구현하는 것이 필요합니다 List, 그렇지 않습니다 Set. API 또는 다른 곳에서 구현이 있습니까?

나 자신을 구현하는 것은 어렵지 않아야하지만, 왜 사람들에게 먼저 물어 보지 않겠습니까?

도움이 되었습니까?

해결책

표준 라이브러리에는이를 수행 할 Java 컬렉션이 없습니다. LinkedHashSet<E> a와 유사하게 주문을 보존합니다 List, 하지만 세트를 감싸면 List 당신이 그것을 사용하고 싶을 때 List 당신은 당신이 원하는 의미를 얻을 것입니다.

대안 적으로, 커먼즈 컬렉션 (또는 commons-collections4, 일반 버전의 경우) a List 이미 원하는 것을 수행합니다. SetUniqueList / SetUniqueList<E>.

다른 팁

여기에 내가 한 일과 그것이 작동합니다.

내가 있다고 가정합니다 ArrayList 내가 한 첫 번째 일과 함께 일하는 것은 새로운 것을 만들었습니다. LinkedHashMap.

LinkedHashSet<E> hashSet = new LinkedHashSet<E>()

그런 다음 새 요소를 LinkedHashSet. ADD 메소드는 변경되지 않습니다 LinkedHasSet 새 요소가 복제 인 경우 False를 반환합니다. 그래서 이것은 추가하기 전에 테스트 할 수있는 조건이됩니다. ArrayList.

if (hashSet.add(E)) arrayList.add(E);

이것은 중복이 배열 목록에 추가되는 것을 방지하는 간단하고 우아한 방법입니다. 원한다면 캡슐화하고 클래스에서 ADD 메소드를 재정의 할 수 있습니다. ArrayList. 다루는 것을 잊지 마십시오 addAll 요소를 반복하고 추가 방법을 호출함으로써.

그래서 여기 내가 결국 한 일이 있습니다. 나는 이것이 다른 사람을 돕기를 바랍니다.

class NoDuplicatesList<E> extends LinkedList<E> {
    @Override
    public boolean add(E e) {
        if (this.contains(e)) {
            return false;
        }
        else {
            return super.add(e);
        }
    }

    @Override
    public boolean addAll(Collection<? extends E> collection) {
        Collection<E> copy = new LinkedList<E>(collection);
        copy.removeAll(this);
        return super.addAll(copy);
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> collection) {
        Collection<E> copy = new LinkedList<E>(collection);
        copy.removeAll(this);
        return super.addAll(index, copy);
    }

    @Override
    public void add(int index, E element) {
        if (this.contains(element)) {
            return;
        }
        else {
            super.add(index, element);
        }
    }
}   

Dhiller의 대답을 진지하게 고려해야합니다.

  1. 객체를 중복없는 목록에 추가하는 것에 대해 걱정하는 대신 세트 (모든 구현)에 추가하여 중복을 필터링합니다.
  2. 목록이 필요한 메소드를 호출 해야하는 경우 new ArrayList(set) (또는 a new LinkedList(set), 무엇이든).

나는 당신이 게시 한 솔루션이라고 생각합니다 NoDuplicatesList 주로 몇 가지 문제가 있습니다 contains() 메소드, 플러스 클래스는 귀하에게 전달 된 컬렉션의 중복 확인을 처리하지 않습니다. addAll() 방법.

목록이있는 세트를 캡슐화하지 않겠습니까?

new ArrayList( new LinkedHashSet() )

이것은 실제 컬렉션 마스터 인 사람을위한 다른 구현을 남깁니다. ;-)

나는 그런 무언가가 필요했기 때문에 Commons 컬렉션에 가서 Setuniquelist를 사용했지만 성능 테스트를 실행했을 때 세트를 사용하고 배열을 사용하여 배열을 얻으려면 케이스와 비교하여 최적화되지 않은 것으로 나타났습니다. set.toArray () 메소드, setuniqueTest는 다른 구현과 비교하여 100,000 문자열을 채우는 데 20 : 1 시간이 걸렸으며, 이는 큰 차이가되므로 성능에 대해 걱정하면 세트를 사용하는 것이 좋습니다. setuniquelist의 논리가 필요하지 않으면 다른 솔루션을 확인 해야하는 경우 Setuniquelist를 사용하는 대신 배열을 받으십시오 ... 다른 솔루션을 확인해야합니다.

테스트 코드 메인 방법 :

public static void main (String [] args) {

SetUniqueList pq = SetUniqueList.decorate(new ArrayList());
Set s = new TreeSet();

long t1 = 0L;
long t2 = 0L;
String t;


t1 = System.nanoTime();
for (int i = 0; i < 200000; i++) {
    pq.add("a" + Math.random());
}
while (!pq.isEmpty()) {
    t = (String) pq.remove(0);
}
t1 = System.nanoTime() - t1;

t2 = System.nanoTime();
for (int i = 0; i < 200000; i++) {
    s.add("a" + Math.random());
}

s.clear();
String[] d = (String[]) s.toArray(new String[0]);
s.clear();
for (int i = 0; i < d.length; i++) {
    t = d[i];

}
t2 = System.nanoTime() - t2;

System.out.println((double)t1/1000/1000/1000); //seconds
System.out.println((double)t2/1000/1000/1000); //seconds
System.out.println(((double) t1) / t2);        //comparing results

}

Mohammed Sleem에 감사합니다http://abusleem.net/blog

참고 : 걸리지 않습니다 서브리스트 고려한 구현.

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class UniqueList<T> extends ArrayList<T> {

    private static final long serialVersionUID = 1L;

    /** Unique elements SET */
    private final Set<T> set=new HashSet();

    /** Used by addAll methods */
    private Collection<T> addUnique(Collection<? extends T> col) {
        Collection<T> unique=new ArrayList();
        for(T e: col){
            if (set.add(e)) unique.add(e);
        }
        return unique;
    }

    @Override
    public boolean add(T e) {
        return set.add(e) ? super.add(e) : false;
    }

    @Override
    public boolean addAll(Collection<? extends T> col) {
        return super.addAll(addUnique(col));
    }

    @Override
    public void add(int index, T e) {
        if (set.add(e)) super.add(index, e);
    }

    @Override
    public boolean addAll(int index, Collection<? extends T> col) {
        return super.addAll(index, addUnique(col));
    }

}

그만큼 수집 인터페이스에 대한 문서 말 :

세트 - 중복 요소를 포함 할 수없는 컬렉션.
목록 - 순서 컬렉션 (때로는 시퀀스라고 함). 목록에는 중복 요소가 포함될 수 있습니다.

따라서 복제를 원하지 않으면 목록을 사용해서는 안됩니다.

안에 add 방법, 사용하지 않는 이유 HashSet.add() 대신 복제를 확인합니다 HashSet.consist(). HashSet.add() 돌아올 것입니다 true 중복이없는 경우 false 그렇지 않으면.

내 머리 꼭대기에서 목록은 복제를 허용합니다. 빠르게 구현할 수 있습니다 UniqueArrayList 그리고 모든 것을 무시합니다 add / insert 확인할 기능 contains() 상속 된 방법을 호출하기 전에. 개인적으로 사용하기 위해서만 구현할 수 있습니다 add 미래의 프로그래머가 다른 방식으로 목록을 사용하려고 할 경우를 대비하여 사용하는 방법을 사용하여 다른 사람을 무시하고 다른 사람을 대체합니다.

나는 방금 내 자신의 작은 도서관에서 내 자신의 독창적 인 것을 이렇게 만들었다.

package com.bprog.collections;//my own little set of useful utilities and classes

import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Jonathan
*/
public class UniqueList {

private HashSet masterSet = new HashSet();
private ArrayList growableUniques;
private Object[] returnable;

public UniqueList() {
    growableUniques = new ArrayList();
}

public UniqueList(int size) {
    growableUniques = new ArrayList(size);
}

public void add(Object thing) {
    if (!masterSet.contains(thing)) {
        masterSet.add(thing);
        growableUniques.add(thing);
    }
}

/**
 * Casts to an ArrayList of unique values
 * @return 
 */
public List getList(){
    return growableUniques;
}

public Object get(int index) {
    return growableUniques.get(index);
}

public Object[] toObjectArray() {
    int size = growableUniques.size();
    returnable = new Object[size];
    for (int i = 0; i < size; i++) {
        returnable[i] = growableUniques.get(i);
    }
    return returnable;
    }
}

다음과 같은 것처럼 보이는 TestCollections 수업이 있습니다.

package com.bprog.collections;
import com.bprog.out.Out;
/**
*
* @author Jonathan
*/
public class TestCollections {
    public static void main(String[] args){
        UniqueList ul = new UniqueList();
        ul.add("Test");
        ul.add("Test");
        ul.add("Not a copy");
        ul.add("Test"); 
        //should only contain two things
        Object[] content = ul.toObjectArray();
        Out.pl("Array Content",content);
    }
}

잘 작동합니다. 아직 세트에 추가 된 경우, 이미없고 객체 배열뿐만 아니라 반환 가능한 배열리스트가있는 경우 세트에 추가됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top