4

So I have three enums and I want to make an ArrayList out of them. Here's my code:

enum Outlook {
    SUNNY, RAINY, CLOUDY
}
enum Temperature {
    HOT, COLD, MILD
}
enum Humidity {
    HIGH, NORMAL, LOW
}

And I want my ArrayList to look something like:

{Outlook, Temperature, Humidity}

Here's what I've tried:

ArrayList<Enum> attributes = new ArrayList<Enum>();
attributes.add(Temperature);

But already Eclipse tells me "Temperature cannot be resolved to a variable". Any idea how to achieve what I'm aiming for here?

Alexis King
  • 43,109
  • 15
  • 131
  • 205
anon_swe
  • 8,791
  • 24
  • 85
  • 145
  • 4
    What is your final goal when doing this? What are you trying to accomplish? I'm asking because there is probably a better/cleaner solution. – gonzo Jan 14 '16 at 22:09
  • 1
    You may want a `List>>` and call `list.add(Temperature.class)`. – assylias Jan 14 '16 at 22:10
  • @assylias That seemed to work but what specifically does it do? – anon_swe Jan 14 '16 at 22:13
  • @gonzo I'm trying to have a collection of each of these enums (their classes I guess) so that I can call a function on each of them. I'll basically loop through the collection, calling the function on each... – anon_swe Jan 14 '16 at 22:13
  • 1
    @AndyThomas I want to loop through all of the classes (Outlook, Temp, Humidity) and, for each of them, calculate information gain. This is a function that makes use of each possible value of a given attribute (Outlook, Temp, Humidity). Does that make sense? – anon_swe Jan 14 '16 at 22:27
  • ArrayList>> attributes = new ArrayList>>(); attributes.add(Outlook.class); attributes.add(Temperature.class); attributes.add(Humidity.class); attributes.add(Windy.class); attributes.add(Classification.class); Seems to work...not totally sure why I have to do .class though... – anon_swe Jan 14 '16 at 22:31
  • Is it the case that the outlook contains information about the temperature and humidity? – Makoto Jan 14 '16 at 22:31
  • @Makoto no, it doesn't – anon_swe Jan 14 '16 at 22:32
  • Fair enough. In that case, **what is the end goal**? How do these elements relate to each other? This is why I asked if outlook contained that information. It sounds like you need another class to contain this information. – Makoto Jan 14 '16 at 22:32
  • If order doesn't matter to you, have you looked at `EnumSet`? Sounds like you're just trying to iterate. Example: http://stackoverflow.com/questions/11825009/what-does-enumset-really-mean – riddle_me_this Jan 14 '16 at 22:54

4 Answers4

2

I'm surmising that you want the names of the enums themselves, and not their values. As such, try the following code:

public static void main (String[] args) throws java.lang.Exception
{
    List<Class<? extends Enum>> myEnums = new ArrayList<>();
    myEnums.add(Outlook.class);
    myEnums.add(Temperature.class);
    myEnums.add(Humidity.class);
    System.out.println(myEnums);
}

enum Outlook {
    SUNNY, RAINY, CLOUDY
}
enum Temperature {
    HOT, COLD, MILD
}
enum Humidity {
    HIGH, NORMAL, LOW
}

You can see the demo here which will output:

[class Ideone$Outlook, class Ideone$Temperature, class Ideone$Humidity]

If you strictly need something like:

[Outlook, Temperature, Humidity]

and just can't like the extra class Ideone$... info then we can add some extra sophistication.

entpnerd
  • 10,049
  • 8
  • 47
  • 68
  • This is perfect. Do you mind explaining the type of your arrayList? – anon_swe Jan 14 '16 at 22:48
  • 1
    I'm not entirely sure what exactly you mean "*type of your ArrayList*" but I think that you're referring to the *Class extends Enum>* type. What you are really adding to the `ArrayList` are the class objects of the enums, themselves, and not their values. Each enum class extends the `Enum` class. So I'm basically saying: Create a list where the type is a *class* (not an object) where each added class is a Java enumeration. Let me know if that answer isn't sufficient or you need more info. – entpnerd Jan 14 '16 at 22:52
1

I want to loop through all of the classes (Outlook, Temp, Humidity) and, for each of them, calculate information gain. This is a function that makes use of each possible value of a given attribute (Outlook, Temp, Humidity).

One possibility would be to define a common interface implemented by all the attributes. This would allow your information-gain function to use the same interface regardless of attribute. And no reflection is required. For example:

interface IAttribute {
    Enum<?>[] getValues();
    String getName();
}

This interface applies to attribute classes as a whole, and not a particular attribute value. Here's one way to do that.

private static final class OutlookAttribute implements IAttribute {
    enum Outlook { SUNNY, RAINY, CLOUDY }

    @Override
    public Outlook[] getValues() { return Outlook.values(); }

    @Override
    public String getName() { return "Outlook"; }
}

// And similarly for Temperature and Humidity

Now you can create a list of attributes to pass to your function.

List<IAttribute> attributes = new ArrayList<>();
attributes.add( new OutlookAttribute() );
attributes.add( new TemperatureAttribute() );
attributes.add( new HumidityAttribute() );

And your function definition can iterate through attributes.

for ( IAttribute attribute : attributes ) {
   Object[] values = attribute.getValues();
   ...
   for ( Object value : values ) {
      ...
   }
   ...
}
Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
0

You need to specify which values to add:

attributes.add(Temperature.HOT);
attributes.add(Temperature.COLD);

Temperature all alone evaluates to a class, but your ArrayList can only contain Enums (Temperature.HOT, Humidity.HIGH...)

Mohammed Aouf Zouag
  • 17,042
  • 4
  • 41
  • 67
0

If you need the all values from a enum typ. Use Enumtyp.values().

public interface EnumInterface {
        public static enum Outlook {
            SUNNY, RAINY, CLOUDY
        }
        public static enum Temperature {
            HOT, COLD, MILD
        }
        public static enum Humidity {
            HIGH, NORMAL, LOW
        }
    }



    public class EnumImp {
        private static ArrayList<Enum> list = new ArrayList<>();

        public void addUnits() {
            EnumInterface.Outlook[] outlookValues = EnumInterface.Outlook.values();
            EnumInterface.Temperature[] temperatureValues = EnumInterface.Temperature.values();
            EnumInterface.Humidity[] humidityValues = EnumInterface.Humidity.values();

            for (int i = 0; i < outlookValues.length; i++) {
                list.add(outlookValues[i]);
            }
            for (int i = 0; i < temperatureValues.length; i++) {
                list.add(temperatureValues[i]);
            }
            for (int i = 0; i < humidityValues.length; i++) {
                list.add(humidityValues[i]);
            }

        }

        public void output() {
            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
        }
    }

    public class TestEnum {

        public static void main(String[] args) {
            EnumImp e = new EnumImp();
            e.addUnits();
            e.output();
        }
    }
Z.B
  • 61
  • 8
  • 1
    From the OP's comment [with emphasis added]: *"I want to loop through all of the **classes** (Outlook, Temp, Humidity) and, for each of them, calculate information gain."* – Andy Thomas Jan 14 '16 at 22:47