Java Enums can implement Interfaces

Something which came as a surprise to me but ended up quite useful, was that enums in Java can also implement interfaces.

A typical enumeration in Java, introduced in Java 5, looks like a String value, but also introduces other features which make them a particularly useful language feature. Besides looking like an typical enumeration with a finite ordered list of values, it is also possible to attach additional information to each enumeration value.

A basic enumeration, which defines the four suits in a typical set of cards looks like this:

public enum Suit 
{ CLUBS, DIAMONDS, HEARTS, SPADES }

To attach additional information to the enumerated type, add a private constructor, add a private field, and get each enumeration value to call the new constructor.

public enum Numbers {
	One(1), Two(2), Three(3);

	private Numbers(int value)
	{
		this.value = value;
	}
	
	public int getValue()
	{
		return this.value;
	}
	
	private int value;
}

In the example above, we also introduced the getValue() method. This introduces the concept of behaviour to our enumeration; not something we would normally consider. It also lends itself to the idea of common behaviour between enumerated types.

To show how this works, consider an interface which defines the mapping between a class and a table.

public interface DatabaseMapping {
	public String getType();
	public boolean isKey();
	public boolean isNullable();
	//public String name();
}

The method name() is commented for now, we’ll get back to that in a minute.

To use this, we can now create a new Java class and then define the mapping of that class to a database.

public class Person {
	public String getFirstname() {
		return firstname;
	}
	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}
	public String getLastname() {
		return lastname;
	}
	public void setLastname(String lastname) {
		this.lastname = lastname;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	private String firstname;
	private String lastname;
	private int age;
}

(I realise there are better ways to map a class to a database table, this example is contrived) When we define the mapping from our class to our table, we can define a separate mapping class. We create this class, we will make it an enumeration and allow each class/database field to be a member in an enumeration.

public enum PersonMapping {
	personId, firstname, lastname, age;
}

Using the trick where we are able to attach additional information to enumerated types, we define some of the database mapping details:

public enum PersonMapping {
	personId("INTEGER", true, false), 
	firstname("TEXT", false, false), 
	lastname("TEXT", false, false),
	age("INTEGER", false, false);
	private PersonMapping(String type, boolean key, boolean nullable )
	{
		this.type = type;
		this.key = key;
		this.nullable = nullable;
	}
	public String getType() {
		return type;
	}
	public boolean isKey() {
		return key;
	}
	public boolean isNullable() {
		return nullable;
	}
	private final String type;
	private final boolean key;
	private final boolean nullable;
}

So now we are able to use the enumeration to iterate the fields and do some database stuff. For the moment we’ll hold off including the interface.

public String dbTableCreate(String tableName) {
	StringBuilder builder = new StringBuilder("Create table ");
	builder.append(tableName);
	builder.append("(");
	for (PersonMapping column : PersonMapping.values()) {
		builder.append(column.name());
		builder.append(" ");
		builder.append(column.getType());
		builder.append(column.isKey() ? " primary key" : "");
		builder.append(", ");
	}
	builder = new StringBuilder(builder.substring(0, builder.length() - 2));
	builder.append(");");
	return builder.toString();
}

Which looks fine for our PersonMapping enumerated type, but doesn’t allow us to plug in different class-to-database mappings. Time to introduce the interface. Looking closely at the code above, we need to use two of the additional methods available to all enumerations, name() and values(). The first returns the text name of the current enumerated value, and the second allows us to access the values that make up this enumerated type.

First add the interface to the enumeration:

public enum PersonMapping implements MappingEnum{

Uncomment the name() method so that it can be accessed from the interface.

public interface MappingEnum {
	public String getType();
	public boolean isKey();
	public boolean isNullable();
	public String name();
}

Final piece of the puzzle is to write the dbTableCreate() above to allow it to be reused with other enumerated types. The problem we need to work around is that the values() method is static, making it difficult to pass the enumerated type to the method. The simple solution is to call the method explicitly and pass the values:

dbTableCreate("tableName", PersonMapping.values()));

… and realise that we can now receive the values using the interface …

public String dbTableCreate(String tableName, MappingEnum[] values) {
	StringBuilder builder = new StringBuilder("Create table ");
	builder.append(tableName);
	builder.append("(");
	for (MappingEnum column : values) {
		builder.append(column.name());
		builder.append(" ");
		builder.append(column.getType());
		builder.append(column.isKey() ? " primary key" : "");
		builder.append(", ");
	}
	builder = new StringBuilder(builder.substring(0, builder.length() - 2));
	builder.append(");");
	return builder.toString();
}

Conclusion

* Enumerations can store additional data and have additional methods,
* Enumerations can use interfaces to define behaviour,
* Enumerated item behaviour can be accessed via an interface, the same as regular Java classes,
* The values() method from enumerations can be used to return an array of a interface.

Combined, it allows us to treat enumerated types as both regular Java classes and enumerated types and interact using common behaviour rather than being tied to a single implementation.

first weekend with my new mac

I got my first Mac in 12 years a few days ago.  On Friday, I was able to surf the net.  Now I’ve advanced to doing almost everything I need except for development tools.

What I liked a lot:

  1. It still feels like home
  2. The trackpad lets you scroll so easily.
  3. iChat – thanks Scott! – only important setup was to check the box to automatically save transcripts on the messages part of preferences.
  4. My laser printer worked out of the box. I didn’t need to configure anything!
  5. Ejecting a CD/DVD is a lot more intuitive now than ejecting a disk was on the old Macs. Hmm, is dragging the disk to the trash can going to eject it or wipe it clean. The current icon to eject matches DVD players and is something most people are used to. There’s even a physical button on the keyboard. I also notice that dragging a disk to trash is still an option. This is actually nice in that it doesn’t change the behavior users who have been around a long time are used to. I was upset at how Windows moved everything in Office 2007 as I now waste time finding features. Apple moved things, but not in a way that makes them hard to find.
  6. Having a real UNIX command line and real UNIX system under the hood.

What I found unintuitive: (none of this is terrible, but it takes a little getting used to)

  1. When I wasn’t in stretch resolution, the browser didn’t extend to use the full screen real estate. I get that this is a “feature”, but if all I am using is the browser, I want to use the whole screen!
  2. To look at the site stats for this blog, one needs Flash. The first time I went to that page in Safari it said “missing plugin.” Fair enough. I click on it and get a message that the type is unspecified. This is probably WordPress’s fault and not Apple’s, but still unintuitive.
  3. I keep forgetting that there isn’t isn’t a pop-up when a download has started and then I start it twice. I have to remember to check the downloads list to see it is in progress. Some visual feedback on .dmg files would be nice. (It looks like if I already have the download window open, it does come to the front.)
  4. I understand why secondary clicking is off by default on the trackpad – whether you want bottom right or two finger touch is a personal preference. The default of neither is a surprise though. “right clicking” to choose a command is pretty common.
  5. How to find Mac Help – go to finder and choose help/mac help
  6. I blame Google or Adobe for this since other sites work just fine, but I have the problem where the cursor disappears in plain text mode when using the arrow keys.  The solution will be to get used to using rich text mode.  This was reported over a year ago and I can’t believe nobody fixed.
  7. How to run something as root/admin: “sudo command”.  This *should* be non-intuitive so people don’t do it by accident!
  8. Closing an app via the red x doesn’t release resources. This is actually easier to remember now as it shows up in the Doc. You actually need to quit the app.  This I did remember from last time, but it isn’t obvious.

Interesting configuration:

  1. I understand why secondary clicking is off by default on the trackpad – whether you want bottom right or two finger touch is a personal preference.  The default of neither is a surprise though.  “right clicking” to choose a command is pretty common.
  2. Need to enter your admin password when installing Flash but not Chrome.
  3. Turn on status bar in Safari so can see URLs before click on them.

Some maintenance tasks:

  1. Let battery run down to zero
  2. Checked all hardware works
  3. Print Safari keyboard shortcuts and Mac OS X keyboard shortcuts to start learning them.
  4. Buy a Mac wired keyboard.  I wanted the number pad and navigation options.  I also prefer not to have to replace batteries in as many things.
  5. Buy external hard drive.  Time machine is very easy to use.  Plug it in and go.
  6. Copied files in My Documents folder to Mac via a flash drive.

Installed after first day:

  1. Flash
  2. ClamXAV – Consensus says you don’t need anti-virus. I feel better having it though and know at least one person who does on a Mac. I think it’s cool they include in the feature list that you can use regular expressions!  Not that I’ll need to, but it’s nice someone thinks it is important.
  3. Open Office – The editing I do on my home computer is pretty light.  Except for the time I was preparing for The Server Side Java Symposium and needed PowerPoint.  I’ll cross that bridge when I come to it.
  4. Skype
  5. Dropbox
  6. Postgres and pgadmin – I got a message “Your system seems to be set up with less than 32MB shared memory”.  The postgres readme clearly explained what to do about it.
  7. Tomcat – this was the first thing I downloaded that assumes you know Mac is a UNIX system.  Granted postgres required that knowledge to install, but not to download.  Not a bad assumption since it is a developer tool of course.  I didn’t untar it/install since I’m not up to testing an application locally yet.
  8. Assorted Safari plugins.  (this seems like a good blog post in itself).  I will say at this time that I like how fast the plugins install.  The first two I tried didn’t work until I restarted Safari.  Would have been nice to a prompt to this effect.
  9. Regular readers of this blog may note that Eclipse is not on the list.  Since Indigo comes out in about a week, I’m going to wait for that to install Eclipse.  I can do any development on my old machine until then.

my first mac in 12 years

I bought my first Mac computer.  The last time I had a Mac was 12 years ago.  That Mac and it’s predecessor was as a gift.  It also predated me having the internet at home.  A lot has changed in 12 years!  As I set up the Mac, I’ll be blogging about my experiences, so check back in a week.

Research Online

Apple.com very clearly lets you see your choices.  I was able to find out most of the information I needed there.  I was then able to get my reminding information to decide by starting a thread at CodeRanch.  Now I know what you are thinking – getting advice from an online forum about what to buy isn’t the best idea.  It’s different here because a most of the posters in that thread are fellow moderators who know me well enough to give good advice.  And a couple of the people in that thread are people in NY that I know in real life.  Scott gave good advice too.

Tuesday – Research In store

There was only one of the model I wanted to buy in the store.  Which would be fine except someone was using Facebook extensively on it.  I asked an Apple employee who said people could surf the net for 30 minutes.  So I want to give Apple two thousand dollars, but I have to wait up to 30 minutes for the guy on Facebook!?!  I asked another Apple employee who asked the guy on Facebook to move to a different computer.

Employee #2 was helpful and answered all my questions.  Including stupid ones.  A lot has changed in the twelve years I’ve been on Windows.  I learned it takes four hours to put the RAM upgrade in so I said I would pick up my computer the next day.

I didn’t go to the famous 5th Avenue store to avoid crowds.  There were still crowds, but distributed on three floors crowds are less overwhelming.

Wednesday – Picking up the Mac

In one day, Apple moved the shelves behind the counter which was a little disorienting and had me second guessing what floor I was on.  The pick up was routine.  The large bag was nice and I was able to use it as a backpack.  Which was nice as I wasn’t thrilled about carrying the box in my hands.  Once unwrapped, the laptop will fit in a laptop bag.

I got home late since I went to Ignite after picking up the laptop so didn’t set it up that night.

Thursday – Setting up the Mac

I was able to get online in 10 minutes and to a point where I could do all my regular internet surfing activities in 90 minutes.  This includes time I was checking e-mail and reading the newspaper though.  I’m sure the real effort was less.

To get online:

  1. Unpack box
  2. Plug in laptop and press power button to turn on laptop
  3. See Apple splash screen
  4. Choose English as language
  5. Watch the Welcome movie (I could have done without this, but I suppose it is better than an hourglass)
  6. More language settings
  7. Enter wifi information and apple id
  8. Saw it test the web cam, but choose a stock photo
  9. Choose safari and done – on the internet!

Setup for my regular internet surfing activities (and other things to make me comfortable through the weekend)

  1. Plugin in my old Windows keyboard and mouse until I buy a Mac keyboard and trackpad.  (I keep my laptop about nine inches up and arms length back for home use so use separate peripherals.)  Apple asked me to select a keyboard since it didn’t recognize the type.  The mouse worked without any setup.  I find myself reaching up to the trackpad on the actual laptop instead of using the mouse for scrolling because the trackpad is so much more natural.  Note to self: should have bought the keyboard/trackpad up front.  The current situation is contrived and a bit awkward.
  2. Change screen resolution because default is on the small side.  I chose 1024×768 stretched which feels comfortable.  Probably because that’s the best  resolution I my old Windows XP laptop supported.  Over time I’ll try changing the resolution a little.
  3. Turn on firewall.
  4. Tune energy settings including turning off keyboard lighting.  I have enough light, I don’t need the keyboard creating any.  Besides, I don’t look at the keyboard so that is a waste of energy.
  5. Download Twitter client from App Store.  Entered my credit card info again.  I didn’t realize this was tied to my device (ipad) rather than Apple id.  Was also surprised I had to enter my credit card t download a free app.
  6. Use the browser a little and let it learn my favorite pages.
  7. Download and install Chrome.  There are some websites I don’t like to visit in my primary browser so I can separate the cookies.  Facebook is one of them.  Also, I like to have two gmail accounts open – one for my mail and one for the coderanch book promos.  Having two browsers open lets me keep both logged in.

What’s next

  1. Relearn keyboard shortcuts.  I can get around in the meantime without them and without reading the instructions so this doesn’t need to happen on day one.
  2. Customize the dock
  3. Install open office
  4. Install developer tools
  5. Buy proper keyboard and trackpad
  6. Configure settings in Safari and Chrome.

The stats

Because what kind of tech blog doesn’t post the details:

  • 15 inch monitor
  • 2 GHz quad core processort
  • 8 GB RAM (my previous machine only had 1 GB and RAM is my constraining force.  Granted my previous computer was six years old.)

Conclusion

When I turned on the Mac, my first thought was “it feels like home.”  I can’t believe it has been 12 years since I last had a Mac.  It’s nice to see it again.  It’s also nice to see how much has changed (internet) and how much has stayed the same (menu structure.)  Windows “moved everything” with Office 2007 and it looks like with Windows 7.  Yet my Mac knowledge that is out of date by a decade was enough to find things without instructions.  That says something about usability.

 

The story continues