How do I create nested TreeMaps?
This is somewhat related to my previous question but I've realised that I needed to deal with the issue of nesting earlier in the problem, so here's where I am. (I'm also not far off being a beginner in Java, so please bear with me).
I'm creating a simple booking system for 5 rooms which will take in names, times, room numbers and days. This has to be done using nested TreeMaps. Here's the layout of the data as I see it, where paretheses represent the boundaries of a TreeMap:
(Day, (Room #, (Time, Name)))
As far as I can see, I need one TreeMap for times and names, one for each room, then one for each day. That means one time/name treemap per room per day, which means 1 x 5 x 7 = 35 TreeMaps. Like this:
{Mon, [Room 1, (0600, NameA
0630, NameB
0700, NameC)
Room 2, (0600, NameD
0630, NameE)
Room 3, (0600, NameF
0630, NameG)]
Tues, [Room 1, (0600, Name1
0630, Name2)
Room 2, (0600, Name3
0630, Name4
0700, Name5)]}
(the different bracket types represent the boundaries of the nested TreeMaps)
Having come to that conclusion, my next problem is iterating through a loop to create all those TreeMaps. I can't seem to dynamically generate the TreeMaps using a for loop, because I can't stick a counter's variable number onto the newly-created TreeMap's name.
I did have this:
TreeMap keyDay = new TreeMap();
TreeMap keyRoom = new TreeMap();
TreeMap keyTime = new TreeMap();
but it is only three, which i开发者_C百科s clearly not enough to allow for duplication of keys - any new entries for e.g. '0900' (time key) or e.g. 'Room 1' (room key) will overwrite the old ones.
Does anyone have any suggestions? Would be much appreciated :)
I agree it is really super mega bad. But if you want to implement this functionality, I recommend HashMaps instead. Here is a class that implements the functionality you want:
public class Reservations {
static final int DAY_SUN = 0, DAY_MON = 1, DAY_TUE = 2, DAY_WED = 3, DAY_THU = 4, DAY_FRI = 5, DAY_SAT = 6;
static final int ROOM_1 = 0, ROOM_2 = 1, ROOM_3 = 2, ROOM_4 = 3, ROOM_5 = 4;
private static HashMap<Integer[], String[]> hMap = new HashMap<Integer[], String[]>();
static String [] getStringForValue(Integer[] i){
return hMap.get(i);
}
static TreeSet<String> getOrderedOutputStrings(){
TreeSet<String> set = new TreeSet<String>();
for(Entry<Integer[],String[]> e : hMap.entrySet()){
int day_int = Reservations.getDay(e.getKey());
int room_int = Reservations.getRoom(e.getKey());
int time = Reservations.getTime(e.getValue());
String name = Reservations.getGuestName(e.getValue());
String day = Reservations.dayToString(day_int);
String room = Reservations.roomToString(room_int);
if(time > 0)
set.add("DAY: " + "(" + day_int + ")" + day + " (" + room_int + ")"+ "ROOM: " + room + " :: " + name + " @ " + time);
}
return set;
}
static void setupMap() {
for (int day = 0; day < 7; day++) {
for (int room = 0; room < 5; room++) {
addGuest(day, room, (int)(Math.random()*1000), "Bob TestCase");
}
}
}
static void addGuest(int day, int room, int time, String name) {
Integer[] ref = new Integer[2];
ref[0] = day;
ref[1] = room;
String[] s = new String[2];
s[0] = Integer.toString(time);
s[1] = name;
hMap.put(ref, s);
}
static String[] lookupRoom(int day, int room) {
Integer[] i = new Integer[2];
i[0] = day;
i[1] = room;
return hMap.get(i);
}
static int getDay(Integer[] i){
return i[0];
}
static int getRoom(Integer[] i ){
return i[1];
}
static int getTime(String[] s) {
return Integer.parseInt(s[0]);
}
public static String getGuestName(String[] s) {
return s[1];
}
public static String dayToString(int i){
switch(i){
case 0:
return "SUNDAY";
case 1:
return "MONDAY";
case 2:
return "TUESDAY";
case 3:
return "WEDNESDAY";
case 4:
return "THURSDAY";
case 5:
return "FRIDAY";
case 6:
return "SATURDAY";
default:
return null;
}
}
public static String roomToString(int i){
switch(i){
case 0:
return "ROOM ONE";
case 1:
return "ROOM TWO";
case 2:
return "ROOM THREE";
case 3:
return "ROOM FOUR";
case 4:
return "ROOM FIVE";
default:
return null;
}
}
}
Here is a main that runs the Reservations class:
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Reservations.setupMap(); //Run to test TODO: remove setupMap() from Reservation class
Reservations.addGuest(Reservations.DAY_MON, Reservations.ROOM_2, 1230, "John Doe");
TreeSet<String> set = new TreeSet<String>();
for(String s: Reservations.getOrderedOutputStrings()){
System.out.println(s + "\n");
}
}
}
And finally, using SetupMap and the single entry, it produces:
DAY: (0)SUNDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 423
DAY: (0)SUNDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 637
DAY: (0)SUNDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 731
DAY: (0)SUNDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 424
DAY: (0)SUNDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 427
DAY: (1)MONDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 335
DAY: (1)MONDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 580
DAY: (1)MONDAY (1)ROOM: ROOM TWO :: John Doe @ 1230
DAY: (1)MONDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 700
DAY: (1)MONDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 556
DAY: (1)MONDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 92
DAY: (2)TUESDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 84
DAY: (2)TUESDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 964
DAY: (2)TUESDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 981
DAY: (2)TUESDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 294
DAY: (2)TUESDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 22
DAY: (3)WEDNESDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 216
DAY: (3)WEDNESDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 838
DAY: (3)WEDNESDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 198
DAY: (3)WEDNESDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 494
DAY: (3)WEDNESDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 796
DAY: (4)THURSDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 617
DAY: (4)THURSDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 866
DAY: (4)THURSDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 799
DAY: (4)THURSDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 242
DAY: (4)THURSDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 178
DAY: (5)FRIDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 491
DAY: (5)FRIDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 16
DAY: (5)FRIDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 838
DAY: (5)FRIDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 63
DAY: (5)FRIDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 860
DAY: (6)SATURDAY (0)ROOM: ROOM ONE :: Bob TestCase @ 73
DAY: (6)SATURDAY (1)ROOM: ROOM TWO :: Bob TestCase @ 759
DAY: (6)SATURDAY (2)ROOM: ROOM THREE :: Bob TestCase @ 15
DAY: (6)SATURDAY (3)ROOM: ROOM FOUR :: Bob TestCase @ 115
DAY: (6)SATURDAY (4)ROOM: ROOM FIVE :: Bob TestCase @ 21
That result was generated in less than a single second. I promise that is infinitely more efficient than nested TreeMaps. Good Luck!
One would assume that the day is actually an enum, so the top level map should be an EnumMap
Map<Day, Map<String, Map<Integer, String>>> bookings = new EnumMap<Day, Map<String, Map<Integer, String>>>(Day.class);
Not really an answer, but rather a thought ;)
Indeed, as xappymah pointed out in comments, more natural approach would be to invent domain-specific types for your task. Like:
interface Room {
String getName();
public void bookRoom(Booking booking) throws AlreadyBookedException;
}
interface Person {
String getName();
}
class Interval {
Date startTime;
long duration;
}
interface Booking {
Interval getInterval();
Room getBookedRoom() throws NotBookedYetException;
Set<Person> getParticipants();
}
interface BookingUtils {
Set<Booking> getBookingsForInterval(Interval interval);
Set<Booking> getBookingsOfRoom(Room room);
}
精彩评论