通过编写 MIDI 处理程序自学 Java。程序需要做的一件事是在 MIDI 音符编号和它们相应的紧凑字符串表示之间来回转换。我看着使用枚举设置,但由于命名限制,你不能做类似的事情
c-1, c#-1, ... g9;
因为尖锐和负面(是的,我遵循让你最终得到一个负八度的惯例:P)。
必须在允许的内容和我想要的内容之间进行转换似乎很笨拙。
CNEG1("c-1"),
CSNEG1("c#-1"),
DNEG1("d-1"),
...
G9("g9");
所以我想出了下面的静态导入方案,它工作正常。但是,我想了解更多关于如何使用枚举的信息,而且我有一种预感,它们实际上可能更适合这项任务——只要我能更好地理解其中的来龙去脉。所以这就是我的问题:任何人都可以想出一种优雅的方式来使用枚举方案提供相同的功能吗?此外,这样做会有强有力的论据吗?
public abstract class MethodsAndConstants {
public static final String TONICS[] = {"c","c#","d","d#","e","f","f#","g","g#","a","a#","b"};
static final NoteMap notemap = new NoteMap();
static class NoteMap{
static String map[] = new String[128];
NoteMap() {
for (int i = 0; i < 128; i++){
int octave = i/12 - 1;
String tonic = MethodsAndConstants.TONICS[i%12];
map[i] = tonic + octave;
}
}
}
public static int convert_midi_note(String name){
return indexOf(NoteMap.map, name);
}
public static String convert_midi_note(int note_num){
return NoteMap.map[note_num];
}
public static int indexOf(String[] a, String item){
return java.util.Arrays.asList(a).indexOf(item);
}
}
编辑 - - - - - - - - - - - - - - - - - - - - -
经过深思熟虑,我认为在这种特殊情况下,枚举毕竟可能是矫枉过正。我最终可能只是在这里使用这个代码,同样的静态导入方法,但不再需要像上面的 NoteMap 业务这样的东西。
note_num -> 名称转换非常简单,而 name -> note_num 的东西只是很好的字符串解析乐趣。
public abstract class MethodsAndConstants {
public static final String[] TONICS = {"c","c#","d","d#","e","f","f#","g","g#","a","a#","b"};
static String convert(int i) {
String tonic = MethodsAndConstants.TONICS[i%12];
int octave = (i / 12) - 1;
return tonic + octave;
}
static int convert(String s) {
int tonic = java.util.Arrays.asList(MethodsAndConstants.TONICS).indexOf(s.substring(0,1));
if (s.contains("#")) tonic += 1;
int octave = Integer.parseInt(s.substring(s.length()-1));
if (s.contains("-")) octave -= 2; // case octave = -1
int note_num = ((octave + 1) * 12) + tonic;
return note_num;
}
}