web-dev-qa-db-fra.com

Créer une liste de valeurs uniques

J'ai, en Java, un arraylist avec ces valeurs (beaucoup de lignes, ceci est juste un extrait) 

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

Où les deux premières valeurs sont des chaînes qui contiennent des données et sont stockées dans un seul élément.

Ce que je veux faire, c'est comparer les éléments de données de la chaîne et supprimer, par exemple, le deuxième élément et tous les éléments mentionnés dans cette ligne.

Pour le moment, j'ai utilisé un cycle for pour que tous les 13 éléments comparent la chaîne (afin de comparer uniquement les chaînes de données)

Ma question: puis-je mettre en œuvre d'autres meilleures solutions?

Ceci est mon 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

Créer une liste de valeurs uniques

Vous pouvez utiliser la méthode Set.toArray().

Une collection qui ne contient aucun élément en double. Plus formellement, ensembles ne contient aucune paire d'éléments e1 et e2 tels que e1.equals (e2) et at la plupart un élément nul. Comme son nom l'indique, cette interface modélise l'abstraction de l'ensemble mathématique.

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

39
Dmitry Zagorulkin

Essayez de rechercher les doublons avec une méthode .contains() sur ArrayList avant d’ajouter un nouvel élément.

Ça ressemblerait à quelque chose comme ça

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

Cela devrait éviter les doublons dans la liste, et ne pas gâcher l'ordre des éléments , comme les gens semblent chercher.

53
Anudeep Bulla
HashSet hs = new HashSet();
                hs.addAll(arrayList);
                arrayList.clear();
                arrayList.addAll(hs);
14
Amol Suryawanshi
 //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

Vous pouvez utiliser un ensemble. C'est une collection qui n'accepte pas les doublons.

3
Sorin

Utilisez Set

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

Vous pouvez facilement le faire avec un Hashmap. Vous avez évidemment une clé (qui est les données de chaîne) et quelques valeurs.

Bouclez toutes vos lignes et ajoutez-les à votre carte.

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

Notez que dans ce cas, vous conserverez l'occurrence last des lignes dupliquées. Si vous préférez conserver l’occurrence first et supprimer les autres, vous pouvez cocher la case Map.containsKey(String stringData); avant de placer la carte.

2
Arnaud Denoyelle

Remplacez simplement la méthode boolean equals () de l'objet personnalisé. Supposons que vous avez une liste de tableaux avec les champs personnalisés f1, f2, ... override

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

et vérifiez à l'aide de la méthode ArrayList de la méthode contient (). C'est tout.

1
shuvomiah

Assez tard pour la fête, mais voici mes deux cents:

Utilisez une LinkedHashSet

Je suppose que ce dont vous avez besoin est une collection qui:

  • vous interdit d'insérer des doublons;
  • conserve l'ordre d'insertion.

LinkedHashSet fait ceci. L'avantage par rapport à l'utilisation de ArrayList est que LinkedHashSet a une complexité de O(1) pour l'opération contains, par opposition à ArrayList, qui a O(n).


Bien sûr, vous devez implémenter correctement les méthodes equals et hashCode de votre objet.

1
MC Emperor

Vous pouvez lire du fichier à la carte, où la clé est la date et ignorer la ligne entière si la date est déjà dans la carte

        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

Si vous avez besoin de valeurs uniques, vous devez utiliser l'implémentation de l'interface SET.

0
Sashi Kant

J'utilise la classe d'assistance. Pas sûr que ce soit bon ou mauvais

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

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

Ou version Java8:

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