Effizienter oder moderner? Einlesen und Sortieren einer Textdatei mit Java

8

Ich habe versucht, meine Java-Kenntnisse zu verbessern, um mehr von Java 5 & amp; Java 6. Ich habe mit einigen Programmierübungen herumgespielt. Ich wurde aufgefordert, einen Absatz aus einer Textdatei einzulesen und eine sortierte (absteigende) Liste von Wörtern auszugeben und die Zählung jedes Wortes auszugeben.

Mein Code ist unten.

Meine Fragen sind:

  1. Ist meine Dateieingaberoutine die respektvollste JVM-Ressource?

  2. Ist es möglich, Schritte in Bezug auf das Lesen der Dateiinhalte und das Abrufen des Inhalts in eine Sammlung, die eine sortierte Liste von Wörtern erstellen kann, zu entfernen?

  3. Verwende ich die Collection-Klassen und die Schnittstelle so effizient wie möglich?

Vielen Dank für Ihre Meinung. Ich versuche nur, etwas Spaß zu haben und meine Programmierfähigkeiten zu verbessern.

%Vor%     
Steve 07.06.2011, 16:40
quelle

5 Antworten

4
  1. Es gibt mehr idiomatische Möglichkeiten, alle Wörter in einer Datei in Java zu lesen.   BreakIterator ist eine bessere Methode zum Lesen von Wörtern von einer Eingabe.

  2. Verwenden Sie List<String> anstelle von Array in fast allen Fällen. Array ist technisch nicht Teil von Collection API und es ist nicht so einfach, Implementierungen wie List , Set und Map zu ersetzen.

  3. Sie sollten Map<String,AtomicInteger> verwenden, um Ihre Wörter zu zählen, anstatt die Array immer wieder zu durchlaufen. AtomicInteger ist anders als Integer änderbar, so dass Sie es können nur incrementAndGet() in einer einzigen Operation, die gerade Thread-sicher ist. Eine SortedMap Implementierung würde Ihnen die Wörter in der richtigen Reihenfolge geben.

  4. Mache so viele Variablen, sogar lokale final wie möglich. und erkläre sie richtig, bevor du sie verwendest, nicht an der Spitze, wo ihr beabsichtigter Umfang verloren geht.

  5. Sie sollten fast immer eine BufferedReader oder BufferedStream mit einer geeigneten Puffergröße verwenden, die einem Vielfachen Ihrer Plattenblockgröße entspricht, wenn Sie eine Datenträger-IO ausführen.

Das heißt, sich nicht mit Mikrooptimierungen beschäftigen, bis Sie "korrektes" Verhalten haben.

    
Jarrod Roberson 07.06.2011, 16:52
quelle
2
  • Der SortedMap -Typ könnte effizient genug sein, um speicherfähig zu sein Verwenden Sie hier in der Form SortedMap<String,Integer> (besonders wenn die Wortzahlen wahrscheinlich unter 128 liegen)
  • Sie können dem Scanner -Typ Kundentrennzeichen zum Brechen bereitstellen Streams

Je nachdem, wie Sie die Daten behandeln möchten, können Sie auch die Interpunktion streichen oder für eine erweiterte Wortrennfunktion mit einem Break-Iterator sorgen - siehe java.text -Paket oder das ICU-Projekt.

Außerdem empfehle ich, Variablen zu deklarieren, wenn Sie sie zuerst zuweisen und keine unerwünschten Nullwerte mehr zuweisen.

Um es auszuarbeiten, können Sie Wörter in einer Karte wie folgt zählen:

%Vor%

Aufgrund der Unveränderbarkeit von Integer und des Verhaltens von Autoboxing kann zu einer übermäßigen Objekt-Instanziierung führen für große Datenmengen. Eine Alternative wäre (wie andere vorschlagen), einen veränderlichen int -Wrapper zu verwenden (wobei AtomicInteger ein Formular ist.)

    
McDowell 07.06.2011 16:52
quelle
0

Können Sie Guava für Ihre Hausaufgaben verwenden? Multiset übernimmt die Zählung. Insbesondere LinkedHashMultiset könnte nützlich sein.

    
djg 07.06.2011 16:54
quelle
0

Einige andere Dinge, die Sie vielleicht interessant finden:

Um die Datei zu lesen, können Sie einen BufferedReader verwenden (wenn es ist nur Text).

Dies:

%Vor%

Könnte mit einer erweiterten for-Schleife (der Java-foreach) gemacht werden, wie gezeigt hier .

%Vor%

In Ihrem Fall können Sie einfach ein einzelnes else verwenden, damit die Bedingung nicht erneut überprüft wird (denn wenn die Wörter nicht identisch sind, können sie nur unterschiedlich sein).

%Vor%

Ich denke% length ist hier schneller:

%Vor%     
Lukas Knuth 07.06.2011 16:55
quelle
0

Eingabemethode:

Machen Sie es sich leichter und arbeiten Sie direkt mit Zeichen statt mit Bytes. Zum Beispiel könnten Sie ein FileReader verwenden und es möglicherweise in ein BufferedReader umbrechen. Zumindest würde ich vorschlagen, auf InputStreamReader zu schauen, da die Implementierung, um von Bytes zu Zeichen zu wechseln, bereits für Sie erledigt ist. Meine Präferenz wäre Scanner .

Ich würde lieber null zurückgeben oder eine Ausnahme von Ihrer readIn() Methode werfen. Ausnahmen sollten nicht für die Ablaufsteuerung verwendet werden, aber Sie senden eine wichtige Nachricht an den Aufrufer zurück: Die von Ihnen angegebene Datei war nicht gültig. Was mich zu einem anderen Punkt bringt: Überlegen Sie, ob Sie wirklich alle Ausnahmen oder nur bestimmte Typen abfangen wollen. Sie müssen alle geprüften Ausnahmen behandeln, aber Sie möchten sie möglicherweise anders behandeln.

Sammlungen:

Sie verwenden wirklich keine Collections-Klassen, Sie verwenden ein Array. Ihre Implementierung scheint in Ordnung, aber ...

Es gibt sicherlich viele Möglichkeiten, dieses Problem zu lösen. Ihre Methode - sortieren und dann vergleichen - ist durchschnittlich O (nlogn). Das ist sicher nicht schlecht. Sehen Sie sich eine Möglichkeit an, eine Map -Implementierung (wie HashMap ) zu verwenden, um die Daten zu speichern, die Sie benötigen, während Sie nur den Text in O (n) durchlaufen ( HashMap s get() und put() - und vermutlich contains() - Methoden sind O (1)).

    
Mike M 07.06.2011 17:14
quelle

Tags und Links