3

Java で音符の列挙を作成するにはどうすればよいでしょうか。各音符にはオクターブとキー付き変数があります。これは私がこれまでに持っているものです...

    public enum Notes
    {
            c,
            cS,
            d,
            dS,
            e,
            f,
            fS,
            g,
            gS,
            a,
            aS,
            b;
            int octave;
            boolean isPlaying;
    }

したがって、コードで列挙型にアクセスするときは、次のように記述します...

Notes.c.octave = 4;
Notes.c.isPlaying = true;

ここに私の質問があります: 各オクターブの各ノートに対して isPlaying ブール値を取得するにはどうすればよいですか?

そのようです:

Notes.c.octave.isPlaying = true;

または、次のようにする必要がありますか?

public enum Notes
{
        c1,
        cS1,
        d1,
        dS1,
        e1,
        f1,
        fS1,
        g1,
        gS1,
        a1,
        aS1,
        b1
        c2,
        cS2,
        d2,
        dS2,
        e2,
        f2,
        fS2,
        g2,
        gS2,
        a2,
        aS2,
        b2;

        etc...

        boolean isPlaying;
}

この質問に答えるために時間を割いていただきありがとうございます!

4

6 に答える 6

4

列挙型のフィールドを変更しないでください!!!

その理由は、各インスタンスが (シングルトンのように) JVM 内で一意であり、同じメモを使用する別のスレッドが同じplayingフィールドを共有するためです。これは深刻な設計の誤りです。

Noteまた、列挙型の名前は、plural ではなく、singular にする必要がありますNotes。その理由は明らかです。列挙型の各インスタンスは、複数のメモではなく、1 つのメモを表します。


これを行う正しい方法は、3 つのフィールドを持つクラスを作成することです。

public class Tone {
    private Note note; 
    private int octave;
    private boolean playing;
    // with getters and setters
}

すべての音はフラット♭、シャープ♯、ダブルフラット

于 2012-11-03T05:14:06.867 に答える
1

列挙型ではなくオブジェクトに移動します。以下を持つオブジェクト JavaNote を作成できます。int オクターブ; boolean isPlaying;

なぜ列挙型を気にするのですか?

于 2012-11-03T04:28:41.547 に答える
1

以下のように、デフォルトのoctave変数0isPlaying変数を使用して列挙要素を作成します。false

  public enum Notes
  {
        c(0, false),
        cS(0, false),
        d(0, false),
        dS(0, false),
        e(0, false),
        f(0, false),
        fS(0, false),
        g(0, false),
        gS(0, false),
        a(0, false),
        aS(0, false),
        b(0, false);
        int octave;
        boolean isPlaying;

        Notes(int octave, boolean isPlaying){
            this.octave = octave;
            this.isPlaying = isPlaying;
        }

        int getOctave(){
            return this.octave;
        }

        boolean isPlaying(){
            return this.isPlaying;
        }
   }

これで、列挙型を次のように使用できます。

Notes.a.octave = 5;//assign the value if required
Notes.a.isPlaying = true;//assign the value if required
System.out.println(Notes.a.octave);//this will print 5
System.out.println(Notes.a.getOctave());//this will print 5
System.out.println(Notes.a.isPlaying);//this will print true
System.out.println(Notes.a.isPlaying());//this will print true

お役に立てれば!

于 2012-11-03T04:30:51.203 に答える
1

インスタンスのインスタンスを保存してチェックするisPlayingだけでフラグを取り除く必要はありません。Notes

Notes playingNote = Notes.c1;

演奏ノートを確認する必要がある場合

 playingNote == Notes.c1

変更する必要があるのはコンストラクターだけです。Octave 値を取るコンストラクタを宣言します。

c1(1);
private int octave = 0;
private Notes(int octave){
        this.octave= octave;
}

注: 楽器のオクターブは変化しないと仮定します。ただし、楽器の専門家ではありません。同時に複数のノートを作成するには、EnumSet を使用できます。

于 2012-11-03T04:38:33.103 に答える
0

これは素晴らしい質問です!

私はあなたが最初の部分が正しいと信じています:

/** An enum of the valid note names */

public enum Note {
    c,
    cS,
    d,
    dS,
    e,
    f,
    fS,
    g,
    gS,
    a,
    aS,
    b;
}

プライベートオクターブisPlayingプロパティ、およびNote列挙型のインスタンスを持つクラスを作成する必要があります。

たぶんあなたはこのようなコードになってしまうでしょう:

class InstrumentNote {
    private Note note;
    private int octave = 0;
    private boolean isPlyaing = false;

    public InstrumentNote(Note someNote, int someOctave) {
        note = someNote;
        octave = someOctave;
        isPlaying = false;
    }
}

class TestIt {
    public static void main(String[] args) {
        int octaveCount = 8; // big piano
        Set<Note> instrumentNotes = buildInstrument(octaveCount);
    }

    /** 
     *  Creates a Set of Notes.  A Set is used because each instrument
     *  should consist of a group of unique note instances, based on how
     *  many octaves it has.
     */

    public static Set<InstrumentNote> buildInstrument(int numOctaves) {
        Set<InstrumentNote> noteSet = new TreeSet<InstrumentNote>();
        for (int i = 0; i < numOctaves; i++) {
            for (Note n : Note.values()) {
               noteSet.add(new InstrumentNote(n, i, false));
            }
        }
        return noteSet;
    }


}

オクターブを列挙型の一部にする必要があるかどうかは良い質問です。

ノートのオクターブは変更されるべきではありません...しかし、ノートインスタンスも持つクラスのプライベートメンバーとしてはより適していると思います。

あなたの要件がわからないので、私はそれらを想像しようとしています...

有効なノートのグループ(上に表示)から楽器またはのいずれかを作成できると思います。

これにより、あらゆる種類の柔軟性が得られます。

  • 一連のノートを持つabstarctInstrumentクラスを作成できます
  • さまざまな種類の楽器を実装できます(トランペットは一度に1つの音しか演奏できませんが、ピアノは多くの音を演奏できます)
  • 持続時間、音量、スタイル(スタッカート、レガート)などを含む一連の音符である曲を実装できます...

上記のいくつかを実行したい場合は、メモを並べ替える方法も必要になります(メモのセットを注文できるようにするため)。

これは、Comparatorや、indexまたはorder(または何か)という名前の列挙型プロパティを使用して行うことができます。

NoteComparatorを作成する演習はあなたに任せます。

列挙型にインターフェイスComparableを実装させることができるかどうかはわかりません...

これのいくつかが正確または役立つことを願っています...

于 2012-11-03T04:54:50.600 に答える