Question

First, my code (It is far from perfect, I don't really know what I am doing) is this:

   public enum Chord { MAJOR, MINOR, DIMINISHED, BASS, BASS2 }
   public enum Scales { C, D, E, F, G, A }
public class EnumTest
{
Chord chord;
public EnumTest(Chord chord)
{
    this.chord = chord;
}
public void tellItLikeItIs()
{

switch (chord) {

    case MAJOR:
            for(Scales C : Scales.values())
                System.out.println(C + " " + C.ordinal());
                break;

//I've tried in the CHORD enum going MAJOR(0, 2, 4) but I don't think that was correct
    case MINOR: System.out.println("C, Eb, G");
                break;
    default:
        System.out.println("I screwed up");
        break;

}
}


public static void main(String[] args)
{

EnumTest firstDay = new EnumTest(Chord.MAJOR);
firstDay.tellItLikeItIs();
EnumTest thirdDay = new EnumTest(Chord.MINOR);
thirdDay.tellItLikeItIs();
System.out.println("Here are all Scale degrees" +
                   " and their ordinal values: ");
for(Scales C : Scales.values())
  System.out.println(C + " " + C.ordinal());



}

}

I might be missing a few brackets and things, I had trouble posting some of it using the code tool. My question is, for case MAJOR, I can get the compiler to print C 0, D 1, E 2, etc.. except I only want it to print C, E and G (0, 2, 4). Is there a way to select ONLY these 3 ordinal values for a major chord and print those?

Also, in the Scales enum I also need the sharps (C, C#, D, D#..) except the sharps are 'illegal characters' and I get _MusicChord\Scales.java:2: illegal character: \35 I tried to look into escape characters, but I either didn't understand the article I read or I was looking at the wrong thing. Could someone also tell me how to add the #'s into the Scales class without them being illegal characters? Any help is appreciated

Was it helpful?

Solution

In the following example you can see how you could address some of the problems you are facing:

public class EnumTest
{
    public enum Chord
    {
        MAJOR,
        MINOR,
        DIMINISHED,
        BASS,
        BASS2
    }

    public enum Scales
    {
        C("C"),
        CSharp("C#"),
        E("E"),
        F("F"),
        G("G"),
        A("A");

        private final String printName;

        Scales(String printName)
        {
            this.printName = printName;
        }

        public String getPrintName()
        {
            return printName;
        }

        public String toString()
        {
            return printName;
        }

        private static final Map<Chord, List<Scales>> scalesForChord;

        static
        {
            scalesForChord = new HashMap<Chord, List<Scales>>();

            scalesForChord.put(Chord.MAJOR, Arrays.asList(Scales.C, Scales.E, Scales.G));
        }

        public static List<Scales> getScalesForChord(Chord chord)
        {
            return scalesForChord.get(chord);
        }
    }
}

OTHER TIPS

In addition to the other answers, you should not use .ordinal() because it makes your code harder to extend in the future. Example: What if you have to add an enum and its ordinal is not what you need it it be?

The ordinal is the 'position' of the ENUM in its declaration. In your example this happens to coincide with something that semantically makes sense to your domain.

It is a better idea to draw attention to this semantic importance by having constructors that take these values for the individual ENUMs, like in Gandalf's example. Instead of C("C"), have C("C", 1), and in addition to final String printName; also have a final String whateverThatNumberMeans;

To select only relevant elements of enum use if(c.ordinal() == 1) or better if(Chord.MAJOR.equals(c)) in loop. I hope I understood your question.

The second question is not very clear. If you want to use # as a part of identifier name please not it is impossible. This character is forbidden. But you can use it into toString() implementation if you want.

I hope this helps.

Do { C, Cs, D, ..., A, As, B }. Similarly, you could also do { C, Db, D, ..., A, Bb, B }. As a rule, stick with [[:alpha:]_][[:alnum:]_]* for names.

Try this for your case MAJOR:

case MAJOR:
            for (Scales c : EnumSet.of(Scales.C, Scales.E, Scales.G)) {
                System.out.println(c + " " + c.ordinal());
            }
            break;

and this for your Scales enum:

public enum Scales {
    C, Cs("C#"), D, Ds("D#"), E, F, G, A;
    private final String label;
    private Scales() {
        this.label = name();
    }
    private Scales(String label) {
        this.label = label;
    }
    @Override
    public String toString() { return label; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top