Alex Rivera | Logout

Arrays of Arrays in Java

Asked 2008-08-15T23:07:03.400
17

This is a nasty one for me... I'm a PHP guy working in Java on a JSP project. I know how to do what I'm attempting through too much code and a complete lack of finesse.

I'd prefer to do it right. Here is the situation:

I'm writing a small display to show customers what days they can water their lawns based on their watering group (ABCDE) and what time of year it is. Our seasons look like this: Summer (5-1 to 8-31) Spring (3-1 to 4-30) Fall (9-1 to 10-31) Winter (11-1 to 2-28)

An example might be:

If I'm in group A, here would be my allowed times: Winter: Mondays only Spring: Tues, Thurs, Sat Summer: Any Day Fall: Tues, Thurs, Sat

If I was writing this in PHP I would use arrays like this:

//M=Monday,t=Tuesday,T=Thursday.... etc
$schedule["A"]["Winter"]='M';
$schedule["A"]["Spring"]='tTS';
$schedule["A"]["Summer"]='Any';
$schedule["A"]["Fall"]='tTS';
$schedule["B"]["Winter"]='t';

I COULD make the days arrays (array("Tuesday","Thursday","Saturday")) etc, but it is not necessary for what I'm really trying to accomplish.

I will also need to setup arrays to determine what season I'm in:

$seasons["Summer"]["start"]=0501;
$seasons["Summer"]["end"]=0801;

Can anyone suggest a really cool way to do this? I will have today's date and the group letter. I will need to get out of my function a day (M) or a series of days (tTS), (Any).

Edit
Report

5 Answers

9

Don't try to be as dynamic as PHP is. You could try to first define what you need.

interface Season
{
    public string getDays();
}

interface User
{
    public Season getWinter();
    public Season getSpring();
    public Season getSummer();
    public Season getFall();
}

interface UserMap
{
    public User getUser(string name);
}

And please, read the documentation of Hashtable before using it. This class is synchronized which means that each call is protected against multithreading which really slows the access when you don't need the extra protection. Please use any Map implementation instead like HashMap or TreeMap.

answered 2008-08-16T00:21:05.763
6

It seems like everyone is trying to find the Java way to do it like you're doing it in PHP, instead of the way it ought to be done in Java. Just consider each piece of your array an object, or, at the very least, the first level of the array as an object and each sub level as variables inside the object. The build a data structure that you populate with said objects and access the objects through the data structure's given accessors.

Something like:

class Schedule
{
  private String group;
  private String season;
  private String rundays;
  public Schedule() { this.group = null; this.season = null; this.rundays= null; }
  public void setGroup(String g) { this.group = g; }
  public String getGroup() { return this.group; }
  ...
}

public ArrayList<Schedule> schedules = new ArrayList<Schedule>();
Schedule s = new Schedule();
s.setGroup(...);
...
schedules.add(s);
...

Of course that probably isn't right either. I'd make each season an object, and maybe each weekday list as an object too. Anyway, its more easily reused, understood, and extensible than a hobbled-together Hashtable that tries to imitate your PHP code. Of course, PHP has objects too, and you should use them in a similar fashion instead of your uber-arrays, wherever possible. I do understand the temptation to cheat, though. PHP makes it so easy, and so fun!

answered 2008-08-16T00:28:34.220
3

I'm not a Java programmer, but getting away from Java and just thinking in terms that are more language agnostic - a cleaner way to do it might be to use either constants or enumerated types. This should work in any langauge that supports multi-dimensional arrays.

If using named constants, where, for example:

int A = 0;
int B = 1;
int C = 2;
int D = 3;

int Spring = 0; 
int Summer = 1;
int Winter = 2; 
int Fall = 3;
...

Then the constants serve as more readable array subscripts:

schedule[A][Winter]="M";
schedule[A][Spring]="tTS";
schedule[A][Summer]="Any";
schedule[A][Fall]="tTS";
schedule[B][Winter]="t";

Using enumerated types:

enum groups
{
  A = 0,
  B = 1,
  C = 2,
  D = 3
}

enum seasons
{
  Spring = 0,
  Summer = 1,
  Fall = 2,
  Winter = 3
}
...
schedule[groups.A][seasons.Winter]="M";
schedule[groups.A][seasons.Spring]="tTS";
schedule[groups.A][seasons.Summer]="Any";
schedule[groups.A][seasons.Fall]="tTS";
schedule[groups.B][seasons.Winter]="t";
answered 2008-08-15T23:56:20.010
2

I'm totally at a loss as to why some of you seem to think that throwing gobs of objects at the code is the way to go. For example, there are exactly four seasons, and they don't do or store anything. How does it simplify anything to make them objects? Wing is quite right that these should probably be constants (or maybe enums).

What Bruce needs, at it's heart, is simply a lookup table. He doesn't need a hierarchy of objects and interfaces; he needs a way to look up a schedule based on a season and a group identifier. Turning things into objects only makes sense if they have responsibilities or state. If they have neither, then they are simply identifiers, and building special objects for them just makes the codebase larger.

You could build, e.g., Group objects that each contain a set of schedule strings (one for each season), but if all the Group object does is provide lookup functionality, then you've reinvented the lookup table in a much less intuitive fashion. If he has to look up the group, and then lookup the schedule, all he has is a two-step lookup table that took longer to code, is more likely to be buggy, and will be harder to maintain.

answered 2008-08-16T01:07:35.577
1

Does the "date" have to be a parameter? If you're just showing the current watering schedule the WateringSchedule class itself can figure out what day it is, and therefore what season it is. Then just have a method which returns a map where the Key is the group letter. Something like:

public Map<String,List<String>> getGroupToScheduledDaysMap() {
  // instantiate a date or whatever to decide what Map to return
}

Then in the JSP page

<c:forEach var="day" items="${scheduler.groupToScheduledDaysMap["A"]}">
   ${day}
</c:forEach>

If you need to show the schedules for more than one season, you should have a method in the WateringSchedule class that returns a map where Seasons are the keys, and then Maps of groupToScheduledDays are the values.

answered 2008-08-16T04:35:49.557

Your Answer