Ich habe eine ArrayList<String>
und ich möchte wiederholte Zeichenfolgen daraus entfernen. Wie kann ich das tun?
Antworten
Zu viele Anzeigen?Es ist möglich, Duplikate aus arraylist zu entfernen, ohne HashSet o eine weitere Arrayliste .
Versuchen Sie diesen Code.
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
Die Ausgabe ist
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
Wahrscheinlich ist das ein bisschen übertrieben, aber ich mag diese Art von isolierten Problemen :)
Dieser Code verwendet ein temporäres Set (für die Eindeutigkeitsprüfung), entfernt aber die Elemente direkt aus der ursprünglichen Liste. Da das Entfernen von Elementen innerhalb einer ArrayList eine große Menge an Array-Kopien verursachen kann, wird die remove(int)-Methode vermieden.
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
Wenn wir schon dabei sind, hier ist eine Version für LinkedList (viel schöner!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Verwenden Sie die Marker-Schnittstelle, um eine einheitliche Lösung für List zu präsentieren:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: Ich schätze, dass das generische Zeug hier keinen wirklichen Mehrwert bringt. Tja. :)
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
Wenn Sie bereit sind, eine Bibliothek eines Drittanbieters zu verwenden, können Sie die Methode distinct()
en Eclipse-Kollektionen (ehemals GS Sammlungen).
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
Der Vorteil der Verwendung von distinct()
anstelle der Umwandlung in eine Menge und dann zurück in eine Liste ist, dass distinct()
behält die Reihenfolge der ursprünglichen Liste bei, wobei das erste Vorkommen jedes Elements beibehalten wird. Sie wird durch die Verwendung einer Menge und einer Liste implementiert.
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
Wenn Sie Ihre ursprüngliche Liste nicht in einen Eclipse Collections-Typ konvertieren können, können Sie ListAdapter verwenden, um die gleiche API zu erhalten.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Anmerkung: Ich bin ein Committer für Eclipse Collections.
Wenn Sie den Modelltyp List< T>/ArrayList< T> verwenden, wird Ihnen das hoffentlich helfen.
Hier ist mein Code ohne Verwendung einer anderen Datenstruktur wie set oder hashmap
for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}