webentwicklung-frage-antwort-db.com.de

Erstellen Sie eine Arrayliste mit eindeutigen Werten

Ich habe in Java eine Arrayliste mit diesen Werten (viele Zeilen, dies ist nur ein Auszug) 

20/03/2013 23:31:46 6870 6810 6800 6720 6860 6670 6700 6650 6750 6830 34864 34272 20/03/2013 23:31:46 6910 6780 6800 6720 6860 6680 6620 6690 6760 6790 35072 34496

Dabei sind die ersten beiden Werte Zeichenfolgen, die Daten enthalten und in einem einzigen Element gespeichert sind.

Was ich tun möchte, ist, die String-Datenelemente zu vergleichen und beispielsweise das zweite und alle auf diese Zeile bezogenen Elemente zu löschen.

Im Moment habe ich einen for-Zyklus verwendet, bei dem alle 13 Elemente die Zeichenfolge vergleichen (um nur Datenzeichenfolgen zu vergleichen).

Meine Frage: Kann ich andere bessere Lösungen implementieren?

Das ist mein Code:

import Java.util.Scanner;
import Java.util.List;
import Java.util.ArrayList;
import Java.io.*;
import Java.text.SimpleDateFormat;
import Java.util.Date;

public class Downsampler {
    public static void main(String[] args) throws Exception{

    //The input file
    Scanner s = new Scanner(new File("prova.txt"));


    //Saving each element of the input file in an arraylist 
    ArrayList<String> list = new ArrayList<String>();
    while (s.hasNext()){
        list.add(s.next());
    }
    s.close();

    //Arraylist to save modified values
    ArrayList<String> ds = new ArrayList<String>();

    //
    int i;
    for(i=0; i<=list.size()-13; i=i+14){

            //combining the first to values to obtain data  
            String str = list.get(i)+" "+list.get(i+1);
            ds.add(str);
            //add all the other values to arraylist ds
            int j;
            for(j=2; j<14; j++){
                ds.add(list.get(i+j));
            }

            //comparing data values
            int k;  
            for(k=0; k<=ds.size()-12; k=k+13){
                ds.get(k); //first data string element  
                //Comparing with other strings and delete
                //TODO  
            }
    }
    }
}
28
alessandrob

Erstellen Sie eine Arrayliste mit eindeutigen Werten

Sie können die Set.toArray()-Methode verwenden.

Eine Sammlung, die keine doppelten Elemente enthält. Formell setzt enthalten kein Paar von Elementen e1 und e2, so dass e1.equals (e2) und at meist ein Nullelement. Wie der Name schon sagt, modelliert diese Schnittstelle die mathematische Mengenabstraktion.

http://docs.Oracle.com/javase/6/docs/api/Java/util/Set.html

39

Prüfen Sie mit einer .contains()-Methode in der ArrayList nach Duplikaten, bevor Sie ein neues Element hinzufügen.

Es würde ungefähr so ​​aussehen

   if(!list.contains(data))
       list.add(data);

Das sollte Duplikate in der Liste verhindern und die Reihenfolge der Elemente nicht durcheinander bringen wie es die Leute zu suchen scheinen.

53
Anudeep Bulla
HashSet hs = new HashSet();
                hs.addAll(arrayList);
                arrayList.clear();
                arrayList.addAll(hs);
14
 //Saving each element of the input file in an arraylist 
    ArrayList<String> list = new ArrayList<String>();
    while (s.hasNext()){
        list.add(s.next());
    }

//That's all you need
list = (ArrayList) list.stream().distinct().collect(Collectors.toList());
3
Sadequer Rahman

Sie könnten ein Set verwenden. Es ist eine Sammlung, die keine Duplikate akzeptiert.

3
Sorin

Verwenden Sie Set

      ...
      Set<String> list = new HashSet<>();
      while (s.hasNext()){
         list.add(s.next());
      }
      ...
3

Sie können dies leicht mit einer Hashmap tun. Sie haben offensichtlich einen Schlüssel (dies sind die String-Daten) und einige Werte.

Wiederholen Sie alle Ihre Zeilen und fügen Sie sie Ihrer Karte hinzu.

Map<String, List<Integer>> map = new HashMap<>();
...
while (s.hasNext()){
  String stringData = ...
  List<Integer> values = ...
  map.put(stringData,values);
}

Beachten Sie, dass Sie in diesem Fall das last - Vorkommen doppelter Zeilen beibehalten. Wenn Sie das Vorkommnis first beibehalten und die anderen entfernen möchten, können Sie mit Map.containsKey(String stringData); einen Scheck hinzufügen, bevor Sie die Karte einfügen.

2

Überschreiben Sie einfach die boolesche equals () -Methode des benutzerdefinierten Objekts. Angenommen, Sie haben eine ArrayList mit benutzerdefiniertem Feld f1, f2, ... überschreiben

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof CustomObject)) return false;

    CustomObject object = (CustomObject) o;

    if (!f1.equals(object.dob)) return false;
    if (!f2.equals(object.fullName)) return false;
    ...
    return true;
}

und überprüfen Sie die Methode include () der ArrayList-Instanz. Das ist es.

1
shuvomiah

Ziemlich spät zur Party, aber hier sind meine zwei Cents:

Verwenden Sie eine LinkedHashSet

Ich gehe davon aus, dass Sie eine Sammlung benötigen, die:

  • erlaubt das Einfügen von Duplikaten;
  • behält die Reihenfolge der Einfügung bei.

LinkedHashSet tut dies. Der Vorteil gegenüber einer ArrayList ist, dass LinkedHashSet für die contains-Operation eine Komplexität von O(1) hat, im Gegensatz zu ArrayList, das O(n) hat.


Natürlich müssen Sie die Methoden equals und hashCode Ihres Objekts ordnungsgemäß implementieren.

1
MC Emperor

Sie können von Datei zu Karte lesen, wobei der Schlüssel das Datum ist, und die gesamte Zeile überspringen, wenn sich das Datum bereits in der Karte befindet

        Map<String, List<String>> map = new HashMap<String, List<String>>();

        int i = 0;
        String lastData = null;
        while (s.hasNext()) {
            String str = s.next();
            if (i % 13 == 0) {
                if (map.containsKey(str)) {
                    //skip the whole row
                    lastData = null;
                } else {
                    lastData = str;
                    map.put(lastData, new ArrayList<String>());
                }
            } else if (lastData != null) {
                map.get(lastData).add(str);
            }


            i++;
        }
0
Natalia

Wenn Sie eindeutige Werte benötigen, sollten Sie die Implementierung der SET-Schnittstelle verwenden

0
Sashi Kant

Ich benutze die Helferklasse. Nicht sicher, ob es gut oder schlecht ist

public class ListHelper<T> {
    private final T[] t;

    public ListHelper(T[] t) {
        this.t = t;
    }

    public List<T> unique(List<T> list) {
       Set<T> set = new HashSet<>(list);
        return Arrays.asList(set.toArray(t));
    }
}

Verwendung und Test:

import static org.assertj.core.api.Assertions.assertThat;


public class ListHelperTest {

    @Test
    public void unique() {
        List<String> s = Arrays.asList("abc", "cde", "dfg", "abc");
        List<String> unique = new ListHelper<>(new String[0]).unique(s);
        assertThat(unique).hasSize(3);
    }
}

Oder Java8-Version:

public class ListHelper<T> {
    public Function<List<T>, List<T>> unique() {
        return l -> l.stream().distinct().collect(Collectors.toList());
    }
}

public class ListHelperTest {
    @Test
    public void unique() {
        List<String> s = Arrays.asList("abc", "cde", "dfg", "abc");
        assertThat(new ListHelper<String>().unique().apply(s)).hasSize(3);
    }
}
0
lapkritinis