Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java enum替代了我是如何做到这一点的?_Java_Enums - Fatal编程技术网

Java enum替代了我是如何做到这一点的?

Java enum替代了我是如何做到这一点的?,java,enums,Java,Enums,通过编写MIDI处理程序自学Java。程序需要能够做的一件事是在MIDI音符数字和相应的紧凑字符串表示之间来回转换。我考虑过使用枚举设置,但由于命名限制,您无法执行类似的操作 c-1, c#-1, ... g9; 因为尖锐和消极(是的,我遵循惯例,使你以负八度结束:p) 在允许的和我想要的之间进行转换似乎很笨拙 CNEG1("c-1"), CSNEG1("c#-1"), DNEG1("d-1"), ... G9("g9"); 所以我提出了下面的静态导入方案,效果很好。然而,我想学习更多关于

通过编写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);
    }       
}
诸如此类:

public enum Note {
    CNEG1("c-1"), CSNEG1("c#-1"), DNEG1("d-1");

    private final String tonicOctave;

    private Note(final String tonicOctave) {
        this.tonicOctave = tonicOctave;
    }

    public String getTonicOctave() {
        return this.tonicOctave;
    }

    public static Note fromTonicOctave(final String val) {
        for (final Note note: Note.values()) {
            if (note.getTonicOctave().equals(val)) {
                return note;
            }
        }
        return null;
    }
}

注意,枚举中可以有任意多的参数,因此如果需要分离主音和八度,可以。

可以使用枚举来表示音高,但我可能会尝试在类中封装音高

public class Pitch {

    private final int octave;
    private final Note note;

    public enum Note {
        C("C",4), CSHARP("C#/Db",5), DFLAT("C#/Db",5), //and so on

        private final String thePitch;
        private final int midiAdjust;

        private Note(final String thePitch, final int midiAdjust) {
            this.thePitch = thePitch;
            this.midiAdjust = midiAdjust;
        }

        String getThePitch() {
            return thePitch;
        }

        int getMidiAdjust() {
            return midiAdjust;
        }
    }

    public Pitch(Note note, int octave) {
        this.note = note;
        this.octave = octave;
    }

    public int getMidiNumber(){
        return 12*octave + note.getMidiAdjust();
    }

}
这可以解释这样一个事实:音符(C,C#,D,D#,E…)将是一个重复集,但可以有各种八度音阶,在这种情况下由
int
处理。这将大大减少
枚举的大小


编辑:我在这里添加了几行作为一个想法。您可以将第二个参数传递到枚举的构造函数中,以允许您返回表示音高的MIDI编号。在这篇文章中,我假设MIDI代表的最低数字是A,但我可能在这一点上错了。此外,
12*倍频程
旨在为每个增量添加整个八度音高。您可能需要稍微调整一下,因为我看到您使用的是一种奇怪的符号。

这看起来很有趣。在这一点上我只能勉强开始解析它,但我会做一些研究。编辑只能开始…我想我知道你所说的有能力区分主音和主音的意思,顺便说一句。按照CNEG1(“c”、-1)等,对吗?可能有点用。@TOZ,是的,
CNEG1(“c”,-1)
是可能的好,酷。经过一些努力,我发现使用上面的枚举代码,我可以在数字和名称之间来回转换,如:int midi_note_number=note.fromTonicOctave(my_note_name).ordinal()String my_note_name=note.values()[midi_note_number].getTonicOctave()很好。现在更仔细地看一下“戈伯纳多”的想法。这是一个相关的例子。
public class Pitch {

    private final int octave;
    private final Note note;

    public enum Note {
        C("C",4), CSHARP("C#/Db",5), DFLAT("C#/Db",5), //and so on

        private final String thePitch;
        private final int midiAdjust;

        private Note(final String thePitch, final int midiAdjust) {
            this.thePitch = thePitch;
            this.midiAdjust = midiAdjust;
        }

        String getThePitch() {
            return thePitch;
        }

        int getMidiAdjust() {
            return midiAdjust;
        }
    }

    public Pitch(Note note, int octave) {
        this.note = note;
        this.octave = octave;
    }

    public int getMidiNumber(){
        return 12*octave + note.getMidiAdjust();
    }

}