Frage

Ich weiß, über SortedSet , aber in meinem Fall brauche ich etwas, das List, und nicht Set implementiert. So gibt es eine Implementierung gibt, in der API oder anderswo?

Es sollte nicht schwer sein, mich zu implementieren, aber ich dachte, warum die Leute nicht fragen, hier zuerst?

War es hilfreich?

Lösung

Es gibt keine Java-Sammlung in der Standardbibliothek, dies zu tun. LinkedHashSet<E> Konserven ähnlich einem List Bestellung, obwohl wenn Sie also Ihr Set in einem List wickeln, wenn Sie es als List verwenden möchten, werden Sie die Semantik Sie wollen.

Alternativ kann der Commons Sammlungen (oder commons-collections4, für die generische Version) hat ein List das tut, was Sie wollen schon: SetUniqueList / SetUniqueList<E> .

Andere Tipps

Hier ist, was ich tat, und es funktioniert.

Unter der Annahme, ich ein ArrayList habe mit der ersten Sache zu arbeiten, ich tat, war eine neue LinkedHashMap erstellt.

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

Dann versuche ich mein neues Element in die LinkedHashSet hinzuzufügen. Die Add-Methode ändert nicht die LinkedHasSet und gibt false zurück, wenn das neue Element ein Duplikat ist. So wird dies ein Zustand, den ich vor der Zugabe zu dem ArrayList testen kann.

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

Dies ist eine einfache und elegante Weise, Duplikate zu verhindern, dass zu einer Array-Liste hinzugefügt werden. Wenn Sie möchten, können Sie es in und Überschreibung der Add-Methode in einer Klasse kapseln, die die ArrayList erstreckt. Denken Sie daran, mit addAll zu behandeln durch die Elemente Schleifen und Aufrufen der Add-Methode.

Also hier ist, was ich tat schließlich. Ich hoffe, das hilft jemand anderes.

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

Sie sollten ernsthaft dhiller Antwort betrachten:

  1. Anstatt sich Gedanken über Ihre Objekte in eine doppelte lose Liste hinzufügen, fügen Sie sie zu einem Set (jede Implementierung), die von der Natur werden die Dubletten herauszufiltern.
  2. Wenn Sie die Methode aufrufen müssen, die eine Liste erfordert, wickeln Sie es in einem new ArrayList(set) (oder einem new LinkedList(set), was auch immer).

Ich denke, dass die Lösung, die Sie mit dem NoDuplicatesList geschrieben einige Probleme hat, vor allem mit der contains() Methode, und Ihre Klasse behandelt nicht nach Duplikaten in der Sammlung zu Ihrer addAll() Methode übergeben zu überprüfen.

Warum nicht einen Satz mit einer Liste einkapseln, Art wie:

new ArrayList( new LinkedHashSet() )

Dies lässt die andere Implementierung für jemanden, der ein wahrer Meister der Sammlungen ist; -)

Ich brauchte so etwas, also ging ich zu den commons Sammlungen und verwendet, um die SetUniqueList, aber wenn ich einige Performance-Test lief, fand ich, dass es nicht optimiert scheint auf den Fall zu vergleichen, wenn ich eine Set verwenden möchten und erhalten ein Array mit der Set.toArray () -Methode, die SetUniqueTest 20 nahm: 1 mal zu füllen und dann 100.000 Strings durchqueren auf den anderen implementaion vergleichen, die eine große Sache Unterschied ist, wenn Sie also über die Leistung kümmern, empfehle ich Ihnen zu verwenden, das Set und ein Array erhalten stattdessen die SetUniqueList zu verwenden, es sei denn, Sie wirklich die Logik des SetUniqueList benötigen, dann müssen Sie andere Lösungen prüfen ...

Der Testcode Hauptmethode:

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

}

Viele Grüße Mohammed Sleem http://abusleem.net/blog

. Hinweis: es nicht nehmen subList Implementierung berücksichtigt

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

}

Die Dokumentation für die Sammlung Schnittstellen sagt:

  

Set - eine Kollektion, die keine doppelten Elemente enthalten
.   List - eine geordnete Sammlung (manchmal auch eine Sequenz). Listen können doppelte Elemente enthalten.

Also, wenn Sie Duplikate nicht wollen, sollten Sie wahrscheinlich nicht eine Liste verwenden.

in add Methode, warum nicht HashSet.add() mit Duplikaten statt HashSet.consist() zu überprüfen. HashSet.add() kehrt true wenn kein Duplikat und false sonst.

Aus der Spitze von meinem Kopf, lassen Sie Listen Duplikate. Sie könnten schnell eine UniqueArrayList implementieren und überschreiben alle add / insert Funktionen für contains() zu überprüfen, bevor Sie die geerbten Methoden aufrufen. Für den persönlichen Gebrauch, könnten Sie die add Methode, die Sie verwenden, nur implementieren und die anderen außer Kraft setzen, eine Ausnahme für den Fall zu werfen Zukunft Programmierer versuchen, die Liste auf eine andere Weise zu verwenden.

Ich habe gerade meine eigene UniqueList in meiner eigenen kleinen Bibliothek wie folgt aus:

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

Ich habe eine TestCollections Klasse, die wie folgt aussieht:

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

Adaequat. Denn es macht nicht ist es auf einen Satz ergänzt, wenn sie es nicht schon haben, und es gibt eine Arraylist, die Mehrweg ist, sowie ein Objekt-Array.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top