2017-08-13 3 views
2

J'essaie de connaître la meilleure façon de trier les lignes file.txt dans une collection Java. L'utilisation de orderedSet supprime la duplication et je ne le souhaite pas.PriorityQueue et ArrayList mieux ensemble?

PriorityQueue effectue le travail mais j'ai besoin que ma classe soit Iterable et que j'utilise PriorityQueue.Iterator ne donne pas de résultats triés. Maintenant, je suis confus avec l'utilisation de Arrays.sort ou d'aller avec cette approche: en utilisant PriorityQueue lors de la lecture des lignes à partir du texte, puis en copiant la file d'attente finale sur un tableau pour utiliser son Iterator?

public class FileSorter implements Iterable<String> { 
    // this sorted set contains the lines 
    private PriorityQueue<String> lines0 = new PriorityQueue<>() ; 
    private ArrayList<String> lines = new ArrayList<>(); 

    public void readFiles (String[] filePaths) throws IOException { 
     BufferedReader buf = null; 
     String line ; 
     for (String path:filePaths) { 
      //opening the file 
      buf = new BufferedReader(new FileReader(new File(path))); 

      //iterating through the lines and adding them the collection 
      while ((line = buf.readLine()) != null) { 
       if(line.trim().length() > 0) { //no blank lines 
        lines0.add(line); 
       } 
      } 
     }; 

     //closing the buffer 
     buf.close(); 

     while (!lines0.isEmpty()){ 
      lines.add(lines0.poll()); 
     } 
    } 

    public Iterator<String> iterator() { 
     return lines.iterator(); 
    } 
} 

Merci.

+0

Utilisez [TreeSet] (https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html) – Oleg

+0

Oleg: TreeSet supprime les doublons !! peut-être mon poste n'était pas assez clair, je veux toujours des duplications –

+0

ok, vérifiez ce lien https://stackoverflow.com/questions/8819550/fr/ordonner-dordre-data-structure-qui-affiche-supports-duplicate-keys – Oleg

Répondre

1

Je pense que l'implémentation Iterable n'est pas la meilleure approche car vous devriez préférer la composition à l'héritage, et c'est 2017 après tout; personne n'implémente ses propres classes de collection. Cela dit, que diriez-vous de ce qui suit?

public class Main { 

    public static void main(String[] args) throws IOException, URISyntaxException { 
     for (String line : new FileSorter(new File(Main.class.getResource("test.txt").toURI()).toPath())) { 
      System.out.println(line); 
     } 
    } 

    static class FileSorter implements Iterable<String> { 
     private final Path path; 

     FileSorter(Path path) { 
      this.path = path; 
     } 

     @Override 
     public Iterator<String> iterator() { 
      try { 
       return Files.lines(path) 
         .sorted() 
         .iterator(); 
      } catch (IOException e) { 
       throw new UncheckedIOException(e); 
      } 
     } 
    } 
} 

Étant donné un fichier test.txt dans le même répertoire que la classe Main:

a 
b 
a 
c 

Les impressions du programme ci-dessus:

a 
a 
b 
c 

Iterable a différentes sémantique que Stream parce que le premier peut être réutilisé, alors que ce dernier ne peut être utilisé qu'une seule fois (jusqu'à une opération de terminal). Ainsi, mon implémentation lit le fichier chaque fois que vous appelez iterator(). Je n'ai pas essayé de l'optimiser parce que vous ne l'avez pas demandé, et l'optimisation prématurée est la racine de tous les maux.