From fea10839262960964e1c47781d0a7882f44f5bbf Mon Sep 17 00:00:00 2001 From: "J. Neugebauer" Date: Wed, 27 Jul 2022 13:56:58 +0200 Subject: [PATCH] Javadoc --- src/main/java/schule/ngb/zm/util/Counter.java | 96 +++++++++++-- src/main/java/schule/ngb/zm/util/Timer.java | 132 ++++++++++++++++-- 2 files changed, 209 insertions(+), 19 deletions(-) diff --git a/src/main/java/schule/ngb/zm/util/Counter.java b/src/main/java/schule/ngb/zm/util/Counter.java index 61299fd..4922b1c 100644 --- a/src/main/java/schule/ngb/zm/util/Counter.java +++ b/src/main/java/schule/ngb/zm/util/Counter.java @@ -4,33 +4,101 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; +/** + * Eine Hilfsklasse um Dinge zu zählen. + *

+ * Im einfachsten Fall kann der Zähler als geteilte Zählvariable genutzt werden, + * die mit {@link #inc()} und {@link #dec()} aus verschiedenen Objekten oder + * Methoden verändert werden kann. + *

+ * Der Zähler kann aber auch Objekte zählen, indem die Instanzen an + * {@link #count(Object)} übergeben werden. Am Ende kann mit {@link #getCount()} + * die Anzahl der Objkete abgerufen werden. + *

+ * Handelt es sich bei den Objekten um Zahlen, dann merkt sich ein Zähler auch + * das Maximum, das Minimum, die Summe und den Durchschnitt der gezählten + * Werte. + *

+ * Ein Zähler kann auch komplette Arrays oder Listen von Zahlen zählen und die + * obigen Statistiken auswerten. + */ @SuppressWarnings( "unused" ) public final class Counter { + /** + * Erstellt einen neuen {@code Counter}, der alle Integer im angegebenen + * Array gezählt hat. + * + * @param values Die zu zählenden Werte. + * @return Ein neuer {@code Counter}. + */ + public static Counter fromArray( int[] values ) { + return new Counter().countAll(values); + } + + /** + * Erstellt einen neuen {@code Counter}, der alle Doubles im angegebenen + * Array gezählt hat. + * + * @param values Die zu zählenden Werte. + * @return Ein neuer {@code Counter}. + */ public static Counter fromArray( double[] values ) { return new Counter().countAll(values); } + /** + * Erstellt einen neuen {@code Counter}, der alle Zahlen im angegebenen + * Array gezählt hat. + * + * @param values Die zu zählenden Werte. + * @return Ein neuer {@code Counter}. + */ public static Counter fromArray( Number[] values ) { return new Counter().countAll(values); } + /** + * Erstellt einen neuen {@code Counter}, der alle Zahlen in der angegebenen + * Liste gezählt hat. + * + * @param values Die zu zählenden Werte. + * @return Ein neuer {@code Counter}. + */ public static Counter fromList( List values ) { return new Counter().countAll(values); } - private AtomicInteger count = new AtomicInteger(0); + /** + * Aktuelle Anzahl gezählter Werte. + */ + private final AtomicInteger count = new AtomicInteger(0); + /** + * Statistiken zu den gezählten Werten. + */ private double min = Double.NaN, max = Double.NaN, sum = Double.NaN; - public void Counter() { - + /** + * Erstellt einen neuen, leeren {@code Counter}. + */ + public Counter() { } - public void Counter( int initial ) { + /** + * Ertstellt einen neuen {@code Counter}, der mit dem angegebenen Wert + * initialisiert ist. + * + * @param initial Wert des Zählers zu Beginn. + */ + public Counter( int initial ) { count.set(initial); } + /** + * Gibt die aktuelle Anzahl zurück. + * @return Die aktuelle Anzahl. + */ public int getCount() { return count.get(); } @@ -61,6 +129,8 @@ public final class Counter { } } + + @SuppressWarnings( "UnusedReturnValue" ) public Counter setCount( int count ) { this.count.set(count); return this; @@ -94,10 +164,10 @@ public final class Counter { inc(); // Update stats synchronized( count ) { - sum = Double.isNaN(sum) ? value : sum + value; + sum = Double.isNaN(sum) ? value : sum + value; if( Double.isNaN(max) || max < value ) max = value; - if( Double.isNaN(min) ||min > value ) + if( Double.isNaN(min) || min > value ) min = value; } return this; @@ -120,7 +190,15 @@ public final class Counter { @SuppressWarnings( "UnusedReturnValue" ) public synchronized Counter countAll( double[] values ) { - for( double value: values ) { + for( double value : values ) { + count(value); + } + return this; + } + + @SuppressWarnings( "UnusedReturnValue" ) + public synchronized Counter countAll( int[] values ) { + for( double value : values ) { count(value); } return this; @@ -128,7 +206,7 @@ public final class Counter { @SuppressWarnings( "UnusedReturnValue" ) public synchronized Counter countAll( Number[] values ) { - for( Number value: values ) { + for( Number value : values ) { count(value); } return this; @@ -136,7 +214,7 @@ public final class Counter { @SuppressWarnings( "UnusedReturnValue" ) public synchronized Counter countAll( Collection values ) { - for( Number value: values ) { + for( Number value : values ) { count(value); } return this; diff --git a/src/main/java/schule/ngb/zm/util/Timer.java b/src/main/java/schule/ngb/zm/util/Timer.java index fdfcd64..12de1b0 100644 --- a/src/main/java/schule/ngb/zm/util/Timer.java +++ b/src/main/java/schule/ngb/zm/util/Timer.java @@ -2,77 +2,189 @@ package schule.ngb.zm.util; import java.util.concurrent.TimeUnit; +/** + * Eine Hilfsklasse zur Zeitmessung im Nanosekundenbereich. + *

+ * Die Klasse kann zum Beispiel genutzt werden, um die Laufzeit eines + * Quelltextes zu messen. Wie eine echte Stoppuhr läuft der {@code Timer} + * weiter, wenn nach einem {@link #stop()} wieder {@link #start()} aufgerufen + * wird. Soll die Zeitmessung wieder bei null beginnen, muss vorher + * {@link #reset()} genutzt werden. + *

+ * Die gemessene Zeit kann in {@link #getMillis() Millisekunden} oder + * {@link #getSeconds() Sekunden} abgerufen werden. Wird eine noch größere + * Genauigkeit benötigt, können mit {@link #getTime(TimeUnit)} beliebige + * Zeiteinheiten (zum Beispiel {@link TimeUnit#NANOSECONDS Nanosekunden}) + * abgerufen werden. + *

+ * Die Zeit kann auch bei laufender Uhr abgefragt werden. In dem Fall wird die + * bis zu diesem Zeitpunkt gemessene Zeit zurückgegeben. + */ @SuppressWarnings( "unused" ) public final class Timer { + /** + * Die Basiseinheit für die Zeitmessung. + */ private final TimeUnit baseUnit; + /** + * Ob die Zeitmessung gerade läuft. + */ private boolean running = false; - private long starttime = -1; + /** + * Startzeit der Zeitmessung. -1, wenn noch keine Messung gestartet wurde. + */ + private long start = -1; + /** + * Zeit, die bisher bei allen Zeitmessungen, die gestoppt wurden, insgesamt + * vergangen ist. + */ private long elapsed = 0; + /** + * Erstellt einen neuen {@code Timer} mit Millisekunden als Basiseinheit. + */ public Timer() { this(TimeUnit.MILLISECONDS); } + /** + * Erstellt einen {@code Timer}, der die angegebene Einheit als Basiseinheit + * für {@link #getTime()} benutzt. + *

+ * Um eine Zeitmessung in Nanosekunden durchzuführen, kann der {@code Timer} + * beispielsweise so instanziiert werden: + *


+	 * Timer clock = new Timer(TimeUnit.NANOSECONDS);
+	 * 
+ * + * @param baseUnit Die Basiseinheit für die Zeitmessung. + */ public Timer( TimeUnit baseUnit ) { this.baseUnit = baseUnit; } + /** + * Ob die Zeitmessung gerade läuft. + * + * @return {@code true}, wenn die Zeitmessung mit {@link #start()} gestartet + * wurde. + */ public boolean isRunning() { return running; } + /** + * Startet die Zeitmessung. + *

+ * Wenn zuvor schon eine Zeitmessung gestartet wurde, wird die neue Messung + * zur Summe aller Messungen hinzuaddiert. Soll die Messung bei null + * starten, muss vorher {@link #reset()} verwendet werden: + * + *


+	 * // Timer auf null stellen und sofort starten
+	 * timer.reset().start();
+	 * 
+ * + * @return Dieser {@code Timer} selbst (method chaining). + */ @SuppressWarnings( "UnusedReturnValue" ) public Timer start() { - starttime = System.nanoTime(); + start = System.nanoTime(); running = true; return this; } + /** + * Stoppt den {@code Timer}, wenn er derzeit läuft. Die gemessene Zeit wird + * zur Summe aller gemessenen Zeiten hinzuaddiert. + * + * @return Dieser {@code Timer} selbst (method chaining). + */ @SuppressWarnings( "UnusedReturnValue" ) public Timer stop() { - running = false; - elapsed += System.nanoTime() - starttime; - + if( running ) { + running = false; + elapsed += System.nanoTime() - start; + } return this; } + /** + * Setzt den {@code Timer} auf den Startzustand und löscht alle bisher + * gemessenen Zeiten. Falls die Zeitmessung gerade läuft, wird sie nicht + * gestoppt, sondern läuft vom Zeitpunkt des Aufrufs weiter. + * + * @return Dieser {@code Timer} selbst (method chaining). + */ @SuppressWarnings( "UnusedReturnValue" ) public Timer reset() { - running = false; - starttime = -1; elapsed = 0; + start = -1; + + if( running ) { + start = System.nanoTime(); + } return this; } + /** + * Gibt die Zeit in der Basiseinheit zurück. + * + * @return Die bisher insgesamt gemessene Zeit. + */ public long getTime() { return getTime(baseUnit); } + /** + * Gibt die Zeit in der angegebenen Einheit zurück. + *

+ * Größere Zeiteinheiten werden gerundet und verlieren daher an Genauigkeit. + * Eine Zeitmessung von 999 Millisekunden wird als 0 Sekunden + * zurückgegeben. + *

+ * Um genauere Ergebnisse zu erhalten, kann mit {@link #getMillis()} und + * {@link #getSeconds()} die gemessene Zeit in Minuten beziehungsweise + * Sekunden als Kommazahl abgefragt werden. + * + * @param unit Zeiteinheit + * @return Die bisher insgesamt gemessene Zeit in der gewählten Zeiteinheit. + */ public long getTime( TimeUnit unit ) { if( running ) { - return unit.convert(System.nanoTime() - starttime + elapsed, TimeUnit.NANOSECONDS); + return unit.convert(System.nanoTime() - start + elapsed, TimeUnit.NANOSECONDS); } else { return unit.convert(elapsed, TimeUnit.NANOSECONDS); } } + /** + * Gibt die gemessene Zeit in Millisekunden (gerundet) zurück. + * + * @return Die gemessene Zeit in ms. + */ public int getMillis() { if( running ) { - return (int) ((System.nanoTime() - starttime + elapsed) / 1000000); + return (int) ((System.nanoTime() - start + elapsed) / 1000000); } else { return (int) (elapsed / 1000000); } } + /** + * Gibt die gemessene Zeit in Sekunden zurück. + * + * @return Die gemessene Zeit in s. + */ public double getSeconds() { if( running ) { - return (System.nanoTime() - starttime + elapsed) / 1000000000.0; + return (System.nanoTime() - start + elapsed) / 1000000000.0; } else { return elapsed / 1000000000.0; }