Suche passende Datenstruktur für 2 Einträge

Moin moin,

nachdem ich endlich rausgefunden hab wie man Töne wiedergeben kann etc. hab ich das nächste Problem. Damit ich nicht total schrottigen Quellcode schreibe brauche ich nun irgendeine Datenstruktur für mein Programm. Ziel ist es einen Ton abzuspeichern (z.B. A) und die dazugehörige Frequenz (zB. 69).

Sollte also ungefähr so aussehen zum schluss:

Code:
0: [code] [64]
1: [D] [65]
2: [E] [66]
3: [F] [67]
4: [G] [68]
5: [A] [69]

usw...

Ziel ist es nämlich am Ende eine Funktion zu besitzen:

Java:
playTone(char note);

die mir anhand des parameters den richtigen Ton spielt (Die FETT gedruckten Parameter wären die Ergebnisse aus der Datenstruktur):

Java:
playTone('C');

würde also den Ton C spielen:

Java:
msg.SetMessage(ShortMessage.NOTE_ON, 0, [B]64[/B], 64);


Hoffe einer kann mir helfen hab echt keine Idee...Hab mir mal Enum angesehen aber glaube das ist nicht das richtige für dieses Problem^^
 
Zuletzt bearbeitet von einem Moderator:
A

As3

Gast
Vielleicht [JAPI]Map[/JAPI] ([JAPI]HashMap[/JAPI].
Ich weiß nicht, in wiefern das hilft,
oder ob ich zu nahe-liegend denke.

AS3
 

Michael...

Top Contributor
Möglich wäre da eine Map. z.B.
Java:
Map<Character, Integer> keys = new HashMap<Character, Integer>();
keys.put('C', 64);
keys.put('D', 65);
keys.put('E', 66);
keys.put('F', 67);
An die Frequenz kommt man dann mit:
Java:
int playTone = keys.get('E');
 
S

SlaterB

Gast
gerne übersehen bei so einfachen Keys ist ein Array,
muss nicht komplett befüllt sein, Ränder egal, einfach Größe 500 oder so,

'C' kann als Zahlenwert direkter Array-Index sein, 67 in diesem Fall,
Array jedenfalls schneller, spart hier gar das Autoboxing,
 

TheWhiteShadow

Bekanntes Mitglied
Ich würe es ja als Konstanten oder besser als Enumeration lösen, da die Datenstruktur sich ja nicht ändert.
Java:
public enum Note {
  NOTE_A(64),
  NOTE_B(65);

  private frequenz;

  private getFrequenz() {
    return frequenz
  }

  private Note(int frequenz) {
    this.frequenz = frequenz
  }
}
 
N

nillehammer

Gast
Bei einer so überschaubaren Menge von Einträgen und der angenommenen Unveränderlichkeit, würde ich mich auch TheWhiteShadow's Vorschlag anschließen. Das macht Deinen Quellcode auch viel sprechender. Und der Aufrufer von playTone kann die Methode dann nicht mehr "falsch" aufrufen, was er bei einem char als Parameter könnte (bspw. indem er '!' als Parameter überbibt).

Nur drei kleine Anmerkungen habe ich zu TheWhiteShadow's Code:
- Die Instanzvariable in Zeile 5 muss den Datentyp int haben.
- Sie sollte final sein
- Die Methode getFrequenz muss natürlich public.

Wenn's mehr Einträge werden sollen, dann doch eher Map. Unveränderlichkeit kann man hier mit Collections.unmodifiableMap herstellen.
 
Zuletzt bearbeitet von einem Moderator:
S

Spacerat

Gast
Würde auch eher enums verwenden. Pro Oktave 12 Elemente + 1 * "C" bleiben selbst bei vielen Oktaven noch recht überschaubar.
BTW.: Die Periode sollte final sein. Was wäre falsch daran, sie dann auch noch public zu machen und auf den Getter zu verzichten?
 
N

nillehammer

Gast
[OT]
Spacerat hat gesagt.:
BTW.: Die Periode sollte final sein. Was wäre falsch daran, sie dann auch noch public zu machen und auf den Getter zu verzichten?
Hat für mich etwas mit Kapselung zu tun. Direkter Zugriff auf die Variable heißt, es muss diese Variable für immer und alle Zeit geben oder man nimmt in Kauf, dass Clientcode bei Änderungen nicht mehr kompiliert. Bei Aufruf eines Getters ist es für den Clientcode transparent, woher dieser den int nimmt. In diesem Fall aber vielleicht auch over-engineert, da stimme ich Dir zu.[/OT]
 
Zuletzt bearbeitet von einem Moderator:
S

Spacerat

Gast
[OT]
Hat für mich etwas mit Kapselung zu tun. Direkter Zugriff auf die Variable heißt, es muss diese Variable für immer und alle Zeit geben oder man nimmt in Kauf, dass Clientcode bei Änderungen nicht mehr kompiliert. Bei Aufruf eines Getters ist es für den Clientcode transparent, woher dieser den int nimmt.
Ich schreib' das mal OT...
Genau dabei erschliesst sich mir nicht; Den Methodennamen des Getters könnte man ebenso ändern. Okay, man hätte da noch die @Deprecated-Möglichkeit, aber wäre das der einzige Grund? ???:L[/OT]
 

Marco13

Top Contributor
Im allgemeinen wird die API dadurch zumindest "robuster" gegen Änderungen. Wenn die Frequenz z.B. in Zukunft in kHz gespeichert werden soll, kann man immernoch
return (int)(freq*1000);
schreiben (etwas gestelztes Beispiel, aber von der Idee her...)
 
N

nillehammer

Gast
[OT]
Spacerat hat gesagt.:
aber wäre das der einzige Grund?
Kurze Antwort: Meiner Meinung nach ja. Aber das ist ein sehr wichtiger Grund. Stell Dir mal die nicht ganz unrealistische Aufgabe vor, von Enum-Konstanten mit public Instanzvariablen auf eine Map-basierte Lösung umzuprogrammieren. Wir haben uns aufgrund schlechten API-Designs alle daran gewöhnt, dass Änderungen an einer Stelle immer Änderungen an anderen Stellen nach sich ziehen. Bei einer sauber designeten API müsste das aber nicht sein. Man könnte das an diesem Beispiel hier sehr anschaulich zeigen. Auf der anderen Seite wäre es gerade für dieses Beispiel -wie schon gesagt- aber möglicherweise doch over-engineered.
[/OT]
 

Ark

Top Contributor
Es geht um MIDI, oder? Und wenn ich das richtig verstanden habe, geht es grob um eine Transformation der Bauart [c](Name, Oktave) → Notennummer[/c], richtig?

Machen wir erst einmal die Gegenrichtung. MIDI note #0 ist C-2, also (C, -2), MIDI note #127 ist G8, also (G, 8). Die Notennamen wiederholen sich mit jeder zwölften Note, also:

Code:
Name(Notennummer) = Notennummer mod 12
Oktave(Notennummer) = Notennummer div 12 - 2
wobei die Namen wie folgt nummeriert sind:
Code:
C  →  0
C# →  1
D  →  2
D# →  3
E  →  4
F  →  5
F# →  6
G  →  7
G# →  8
A  →  9
A# → 10
B  → 11
(Enharmonische Verwechslungen etc. spielen in der Abbildung keine Geige. ;) Und zumindest in Deutschland würde man wahrscheinlich statt B den Namen H verwenden, das nur am Rande.)

Damit kommen wir dann auch ganz einfach in die von dir gewünschte Richtung, also [c](Name, Oktave) → Notennummer[/c]:
Code:
Notennummer(Name, Oktave) = (Oktave + 2) * 12 + Name
Nehmen wir mal an, du verwendest für die Namen chars, z.B. 'c' für C und 'G' für G#. Dann würde ich die Umrechnung von Name zu Nummer (siehe gerade aufgeführte Tabelle) einfach eine switch-Anweisung verwenden. Für die Gegenrichtung könnte man auch eine switch-Anweisung verwenden, oder aber ein simples Array. Mit Strings wie "A#" würde dies ännlich ablaufen.

EDIT: Soll also heißen: Man braucht weder eine gigantische [c]Map<String, Integer>[/c] noch Enums noch sonst irgendetwas, sondern entweder nur ein paar simple statische Methoden oder eine Klasse, die aber eigentlich nur ein int kapselt, nämlich die Notennummer, und mit der Umgebung kann man dann über entsprechenden Strings oder chars oder wasweißich kommunizieren.

Ich hoffe, das hilft. Wenn etwas unklar ist, einfach nachfragen. ;)

Ark
 
Zuletzt bearbeitet:
S

Spacerat

Gast
:oops: Da ist was dran. Bei Midi wird die Periodendauer ja gar nicht benötigt. Und dann kann man anstatt "getPeriod()" auch "ordinal()" des enums verwenden. Dann spart man sich im Prinzip sogar noch die Implementierung einer Klasse, die man mit "new" instanzieren müsste.
 
Zuletzt bearbeitet von einem Moderator:

Ark

Top Contributor
Hatte gerade Langeweile … EDIT: … und noch geeignete fromString()-Methoden hinzugefügt.
Java:
public final class MIDINotes{

	private MIDINotes(){
		// private
	}

	public static int note(final char name, final int octave){
		final int n;
		switch(name){
			case 'c':
				n = 0;
				break;
			case 'C':
				n = 1;
				break;
			case 'd':
				n = 2;
				break;
			case 'D':
				n = 3;
				break;
			case 'e':
				n = 4;
				break;
			case 'f':
				n = 5;
				break;
			case 'F':
				n = 6;
				break;
			case 'g':
				n = 7;
				break;
			case 'G':
				n = 8;
				break;
			case 'a':
				n = 9;
				break;
			case 'A':
				n = 10;
				break;
			case 'b':
				n = 11;
				break;
			default:
				throw new Error();
		}
		return (octave + 2) * 12 + n;
	}

	public static char name(final int note){
		switch(note % 12){
			case 0:
				return 'c';
			case 1:
				return 'C';
			case 2:
				return 'd';
			case 3:
				return 'D';
			case 4:
				return 'e';
			case 5:
				return 'f';
			case 6:
				return 'F';
			case 7:
				return 'g';
			case 8:
				return 'G';
			case 9:
				return 'a';
			case 10:
				return 'A';
			case 11:
				return 'b';
			default:
				throw new Error();
		}
	}

	public static int octave(final int note){
		return note / 12 - 2;
	}

	public static String toString(final int note, final boolean useSharp){
		final int octave = octave(note);
		final char name = name(note);

		StringBuilder res = new StringBuilder(4);

		if(useSharp){
			if(name >= 'A' && name <= 'Z'){
				res.append(name).append('#');
			}
			else{
				res.append((char)(name + ('A' - 'a')));
			}
		}
		else{
			res.append(name);
		}
		res.append(octave);

		return res.toString();
	}

	public static String toString(final int note){
		return toString(note, true);
	}

	public static int fromString(final String s, final boolean sharpUsed){
		char name = s.charAt(0);
		final int octave;

		if(sharpUsed){
			if(s.charAt(1) == '#'){
				octave = Integer.parseInt(s.substring(2));
			}
			else{
				name -= 'A' - 'a';
				octave = Integer.parseInt(s.substring(1));
			}
		}
		else{
			octave = Integer.parseInt(s.substring(1));
		}

		return note(name, octave);
	}

	public static int fromString(final String s){
		return fromString(s, true);
	}

	public static void main(final String[] args){
		final boolean useSharp = true;
		for(int i = 0; i < 128; i++){
			System.out.print(toString(i, useSharp) + "\t");
			System.out.println(fromString(toString(i, useSharp), useSharp));
		}
	}
}
(Kommentare habe ich mal weggelassen.)

So, und jetzt die Frage für den Handwerker-versus-Künstler-Thread: Macht das so ein Handwerker oder ein Künstler? ;)

Ark
 
Zuletzt bearbeitet:
Hi,

danke erstmal für die ganzen Antworten. Werd mir das erstmal jetzt alles in Ruhe nochmal ansehen^^ Hatte am Wochenende leider keine Zeit.

Werd dann nochmal schreiben sobald eine Lösung steht^^ (Hoffe ich zumindets ansonsten wenn irgendwelche Fehler auftreten :D )
 
@ Ark

Zu dem Quelltext. Danke erstmal das du dir überhaupt die Mühe gemacht hast :toll:
Aber bekomme nur eine richtige Ausgabe wenn ich 2 kleine Sachen ändere. Ich muss zum einen den Konstruktor auf public stellen und dann in der Main die Klasse MidiNotes instanziieren, damit ich dann toString und fromString ansprechen kann. Aber dann läufts auch^^ Liegt wahrscheinlich daran das ich die Main in einer seperaten Klasse habe.

Werde noch ein bisschen rumm probieren aber glaube das ist so ziemlich die beste Lösung :)
 

Ark

Top Contributor
Ich muss zum einen den Konstruktor auf public stellen und dann in der Main die Klasse MidiNotes instanziieren, damit ich dann toString und fromString ansprechen kann.
???:L
Du weißt aber schon, dass meine main()-Methode nur zum Test da ist, und dass der Konstruktor absichtlich private ist, weil die Klasse nur eine Art Hilfsklasse (ähnlich Math) ist? Wozu brauchst du da bitte Instanzen? Und die toString()-Methode, die du meinst, ist möglicherweise nicht die, die ich geschrieben habe? Achte mal auf die Signatur, und außerdem sind alle Methoden static!

(Nebenbei ist mir noch aufgefallen, dass man statt [c]new Error()[/c] besser [c]new RuntimeException()[/c] verwenden sollte, und zwar in beiden Fällen.)

Ark
 
Also bei mir funktionierts anders nicht. Ich rufe die KLasse MidiNotes noch ind er Klasse Intervall auf und um dort dann die Methode playNote() aufrufen zu können muss ich es so machen:

Java:
MidiNotes mn = new MidiNotes();

mn.playTone();

Alles andere wirft bei mir einen Fehler ???:L
 
S

SlaterB

Gast
was ist denn 'alles andere' und welche Fehler?
99.99999999999999% aller denkbaren Kombinationen von Quelltext, etwa 'glkhlksjlkvj' werfen natürlich Fehler...

statische Methoden ruft man mit Klassenname.methodenName(Parameter) auf
 

Ark

Top Contributor
Also bei mir funktionierts anders nicht. Ich rufe die KLasse MidiNotes noch ind er Klasse Intervall auf und um dort dann die Methode playNote() aufrufen zu können muss ich es so machen:

Java:
MidiNotes mn = new MidiNotes();

mn.playTone();

Alles andere wirft bei mir einen Fehler ???:L
Okay, du meinst vielleicht eine andere Klasse MidiNotes (und eben nicht MIDINotes) oder du hast meine Klasse umbenannt. Jedenfalls durchblicke ich das nicht mehr so ganz.

Ark
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Suche passende substring - Methode! Allgemeine Java-Themen 9
M Suche nach String mit unbekannten characters Allgemeine Java-Themen 53
M Binäre Suche Allgemeine Java-Themen 6
M geometrische Suche Allgemeine Java-Themen 8
S Programm schreiben, das mir aufgrund von Schlagwörtern, die ich im Internet suche, relevante Themen sofort anzeigt. Allgemeine Java-Themen 1
I HTML / XHTML Seite nach Excel exportieren. Suche Lib Allgemeine Java-Themen 12
W Suche Ursache für NPE - woher kommt sie? (Hilfe beim Debugging) Allgemeine Java-Themen 19
W Collections Suche Collection, um Strings mit Indizees versehen Allgemeine Java-Themen 47
O Suche Scripter für alt:V Project! Allgemeine Java-Themen 0
D Suche Quellcode! Allgemeine Java-Themen 8
O Suche Unterstützung für ein OpenSource-Projekt (grafischer Editor) Allgemeine Java-Themen 13
B Bei Email: FW / AW... - Hilfe bei String suche Allgemeine Java-Themen 21
J Suche Alternative zu Jasper Reports Allgemeine Java-Themen 4
W Collections Suche etwas Sorted-List-Artiges...hat jemand eine Idee? Allgemeine Java-Themen 13
M Suche Alternative zu JFreeChart Allgemeine Java-Themen 11
S Warmup für Lineare-Suche mit Zeitmessung Allgemeine Java-Themen 2
K OOP Suche Hilfe + Erklärung für eine Hausaufgabe Allgemeine Java-Themen 1
B Suche nach einem Testprogramm für meine BA Allgemeine Java-Themen 0
D Objekt-Suche mit mehreren optionalen Parametern Allgemeine Java-Themen 6
A NetBeans Suche Programmierer für eine Belegarbeit Allgemeine Java-Themen 11
O Suche größeres Beispiel für WebserverAnwendung mit Java Allgemeine Java-Themen 2
G Google-Suche ist nicht auslesbar?! Allgemeine Java-Themen 18
M Suche aktuelle Apache Poi Bibliothek zum Einbinden in mein Programm Allgemeine Java-Themen 2
L Suche nach CalDav Server API Allgemeine Java-Themen 0
HarleyDavidson Best Practice Suche "Container" für Modulapplikationen Allgemeine Java-Themen 0
S Suche Konzept: Korrektheit des Aufrufers feststellen Allgemeine Java-Themen 7
KaffeeFan Methoden Suche Methode um Programm kurz warten zu lassen Allgemeine Java-Themen 22
B Suche geeignete Datenstruktur Allgemeine Java-Themen 5
L Erste Schritte Suche Java Wiki System? Allgemeine Java-Themen 5
L Suche Geräte für Java SE Embedded Allgemeine Java-Themen 0
S Rekursive Suche in einem Netz Allgemeine Java-Themen 5
F Über Java Google Suche nutzen Allgemeine Java-Themen 11
A Suche Android Programmierer Allgemeine Java-Themen 0
W Suche Framework zur Prüfung von IPv4 und IPv6 Allgemeine Java-Themen 2
A Java - Suche nach Datensatz mit DateChooser Allgemeine Java-Themen 0
S Pattern.Match Suche: For Schleife einbinden und in Liste schreiben Allgemeine Java-Themen 3
M Suche Framework/API für Monitoring-Anwendung Allgemeine Java-Themen 3
F Suche kostenlose GUI für Eclipse Allgemeine Java-Themen 10
H Suche mit Wildcards und boolschen Operatoren Allgemeine Java-Themen 4
A Binäre Suche im Array mit StackOverflowError Allgemeine Java-Themen 3
T Verkettete Suche Allgemeine Java-Themen 6
S RxTx - langsame Port suche Allgemeine Java-Themen 3
D Suche Matrix Libraries Allgemeine Java-Themen 11
S Suche Dependency Injection Container Allgemeine Java-Themen 6
J Suche: Tool zum Auffinden gleichnamiger Klassen (Name und Package gleich) in unteschiedlichen JARs Allgemeine Java-Themen 5
BinaryLogic Input/Output Suche Wörterbuch-Datei Einzahl/Mehrzahl Allgemeine Java-Themen 2
A Suche Algorithmus zum Erstellen eines planaren Graphen Allgemeine Java-Themen 5
D Suche Librarys ähnlich datatables.net + Login Allgemeine Java-Themen 3
Gossi Threads Suche ein (einfaches) Beispiel Allgemeine Java-Themen 5
P Erste Schritte Suche in ArrayList mit Maps Allgemeine Java-Themen 4
F Suche Performanceoptimierung bei Stringsortierung Allgemeine Java-Themen 51
B Suche Datenquelle für lizenz-informationen Allgemeine Java-Themen 5
J Lucene suche in Json (CouchDB) Allgemeine Java-Themen 2
X Suche Softwareimplementierung von Cryptographischen Algorithmen Allgemeine Java-Themen 3
S Suche Tipps für Einstieg in JavaCC Allgemeine Java-Themen 2
R Suche in logfiles mit Lucene / Solr Allgemeine Java-Themen 2
P Suche Datenstruktur Allgemeine Java-Themen 2
M Suche Java-Projekt zum Thema Elektrotechnik Allgemeine Java-Themen 6
F Suche Begriff Allgemeine Java-Themen 2
hdi Suche Icon-Sammlung Allgemeine Java-Themen 7
G Suche "richtiges" Framework/Library Allgemeine Java-Themen 14
slawaweis Suche Klassen für Event Managment und Time Allgemeine Java-Themen 2
P Probleme mit wikipedia quellcode zur binären Suche Allgemeine Java-Themen 6
C Suche Permutationsalgo Allgemeine Java-Themen 6
E Suche nach Foto-Dummy Allgemeine Java-Themen 8
B Suche Paket zum auslesen von Metadaten von Bildern. Allgemeine Java-Themen 4
N suche globale Tastenabfrage Allgemeine Java-Themen 6
P SUCHE: gute Geo Library (freeware) Allgemeine Java-Themen 2
P Suche performante PDF Library Allgemeine Java-Themen 20
data89 Bilder mit Java prüfen - suche dringend Hilfe Allgemeine Java-Themen 8
faetzminator Regex zur Suche von "value-losen" Attributen in HTML Tags Allgemeine Java-Themen 7
S Suche im JTree nach Neuaufbau Allgemeine Java-Themen 4
W Problem bei der Suche (binarySearch) vom deutschen Sonderzeichen "ß" im einem Array Allgemeine Java-Themen 6
D Suche nach passender Datenstruktur Allgemeine Java-Themen 4
S suche library die diagramme darstellen kann Allgemeine Java-Themen 2
T Suche Anhaltspunkt für plattformübergreifende, "unique machine id" ... Allgemeine Java-Themen 12
P WebSerive Suche Allgemeine Java-Themen 15
hdi Suche nach Begriff aus der Programmierung Allgemeine Java-Themen 11
X Suche Java Klasse die Feiertage berechnen kann Allgemeine Java-Themen 2
B suche Deutsche Übersetzung für neuste Eclipse Version Allgemeine Java-Themen 6
Daniel_L Suche nach ganzen Wörtern (wholeword) in Strings? Allgemeine Java-Themen 4
G Regex-Suche nach Worten Allgemeine Java-Themen 3
Antoras Suche Projektarbeit für Gruppe mit 3 Leuten Allgemeine Java-Themen 5
G Perfomante Suche in grosser Datei Allgemeine Java-Themen 6
T Suche Tool Allgemeine Java-Themen 11
D Suche sowas wie Map nur für mehrere Werte Allgemeine Java-Themen 13
D Suche Hilfe zum Rechnerübergreifenden Dateizugriff. Allgemeine Java-Themen 3
M suche speziellen Sortieralgorithmus Allgemeine Java-Themen 3
E javax.comm: Suche eine open source Alternative zu rxtx Allgemeine Java-Themen 8
J Suche regex-Pattern fuer Liste von Zahlen zwischen 0-100 Allgemeine Java-Themen 6
T Suche den großen Calendar Thread ! Allgemeine Java-Themen 2
P Suche Benis IP/Netzwerkadresse JTExtField Allgemeine Java-Themen 2
J Suche Doku um generischen Code zu erstellen. Allgemeine Java-Themen 9
G suche Property alternative Allgemeine Java-Themen 4
C Fehler im Quellcode. Suche in einem Baum Allgemeine Java-Themen 3
S Suche Pendant zu einem VB Befehl Allgemeine Java-Themen 2
T Suche gute JAVA Steuerelemente Allgemeine Java-Themen 2
V Suche RegEx zu (gelöstem) Problem Allgemeine Java-Themen 3
B Suche Browser-Control Allgemeine Java-Themen 4
G Suche Programmierumgebung mit Appletviewer Allgemeine Java-Themen 16

Ähnliche Java Themen


Oben