Join 150,371 Java Programmers for FREE! Get instant access to thousands of Java experts, tutorials, code snippets, and more! There are 1,786 people online right now. Registration is fast and FREE... Join Now!
i am writing a program which would enable me to create a timetable . i am having some problems with putting the all the data that i need into an array specifically a 3d array . i want the count of the first dimension of the array to be able to reference a particular day on the timetable ,the count on the second dimension to represent a particular period and the count on the third dimension to represent the particular venue .all of this should reference a paraticular course that i have scheduled at the intersection of the three dimensions. does aybody have any idea how i can do this this is the structure that i have setup. cell[count for day][count for period][count for venue]=course scheduled at that particular period ,day and venue
this is my sample that i have written
CODE
/* * shell.java * * Created on Jan 28, 2008, 10:11:13 AM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */
int day_id; int period_id; int id; int venue_id; int course_id;
public shell() { }
/*** * this is the array which would represent the timetable structure * the first dimension represents the counter for the day * the second counter represents the counter for the period * the third dimension represnting the number of venues * the value of cell [x][y][z] represents the the course * which has been placed at day x,period y and venue z. **/ public static int[][][] getcell() { int ttcell[][][]=null; shell[] cell = null; Connection conn; ResultSet rw = null; ResultSetMetaData rsmdata = null; Statement stat; int maxd_id=0; int maxp_id=0; int maxv_id=0; String daycell[][]; String periodcell[][]; String venuecell[][]; //String query="select"; try { conn = naak_task_scheduler.database.createconnection(); daycell = database.sellectt("select max(day_id) from day ", conn); periodcell=database.sellectt("select max(period_id) from periods; ", conn); venuecell=database.sellectt("select max(venue_id) from venue", conn); for(int i=0;i<daycell.length;i++) {for(int j=0;j<daycell[i].length;j++) { maxd_id=Integer.parseInt(daycell[i][j]); maxp_id=Integer.parseInt(periodcell[i][j]); maxv_id=Integer.parseInt(venuecell[i][j]); } }
this is the structure that i have setup. cell[count for day][count for period][count for venue]=course scheduled at that particular period ,day and venue
I really wouldn't go this direction. It's exceptionally confusing. You want a design where you can keep all the little bits in your head. At least, as far as you're looking at each bit.
You seem to have a database. Why not represent it's structure in objects? Database links can be represented with arrays of other objects. Something like this:
CODE
class Period { int periodId; //... }
class Day { int dayId; Period[] periods; //... }
class TimeTable { Day[] days; //... public Period[] getPeriodsForDay(int dayId) { ... } }
this is the structure that i have setup. cell[count for day][count for period][count for venue]=course scheduled at that particular period ,day and venue
I really wouldn't go this direction. It's exceptionally confusing. You want a design where you can keep all the little bits in your head. At least, as far as you're looking at each bit.
You seem to have a database. Why not represent it's structure in objects? Database links can be represented with arrays of other objects. Something like this:
CODE
class Period { int periodId; //... }
class Day { int dayId; Period[] periods; //... }
class TimeTable { Day[] days; //... public Period[] getPeriodsForDay(int dayId) { ... } }
Hope this helps.
thanks for your quick reply. i will try and do that . the problem is that i am not too good at working with the java persistence api . which i think is what you are talking about or are you saying that i should create a class where each field in the class would hold all the properties of a particular table which i would get from the database containg all the info i would use??? i will try your first reply now anyways
or are you saying that i should create a class where each field in the class would hold all the properties of a particular table which i would get from the database containg all the info i would use???
Bingo! That's pretty much it.
You're doing things like select max(venue_id) from venue to get a count for an array. Later, you'll want to know what venue maps to array item number 3, right? If you keep it all in arrays, then you need to have some kind of mental map as to how all the pieces fit together. The goal is to describe that explicitly in your code.
Consider something like this
CODE
class Venue { private int venueId; private String name; }
class Venues extends java.util.ArrayList<Venue> { public Venue getVenueForId(int venueId) { ... } }
Now, at some point, create an instance of Venues, read all entries from the database and load it up. You want to know how many you have, call the size() method of that object. When another object, like a course, wants to know the name of its venue, it can just ask the object you already loaded.
There are a number of examples of this kind of approach. It's not using any special framework, just basic OOP principals and design.
/* * cell.java * * Created on Jan 24, 2008, 3:28:28 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */
package naak_task_scheduler;
import java.sql.*; import java.util.*;
/** * * @author Nuku */ public class cell {
public cell() {
}
/** * enables you to perform an sql querry the querry and returns the resultset * @param querry * @return Resultset */ public static ResultSet executequerry(String querry) { Connection conn=null; ResultSet rst=null; Statement stat=null; try { conn=database.createconnection(); stat= conn.createStatement(); rst= stat.executeQuery(querry); } catch(SQLException ex) { ex.printStackTrace();} return rst; }
public static void main(String[] args) { venues ven= new venues();
} } class day { int day_id; String day_short_name; String day_long_name; }
class period { int period_id; Time period_start_time; Time period_end_time; String period; }
class venue { int venue_id; String venue_name; String venue_location; int venue_class_capacity; int venue_exam_capacity; int venue_faculty_id;
}
class venues extends ArrayList { ResultSet rst=null; venue temp=null; public venues() { rst=cell.executequerry("select venue_id,venue_name,venue_location,venue_class_capacity,venue_exam_capacity,venu e_faculty_id from venue"); try { while(rst.next()) { temp.venue_id=rst.getInt("venue_id"); temp.venue_class_capacity=rst.getInt("venue_name"); temp.venue_name=rst.getString("venue_name"); temp.venue_location=rst.getString("venue_location"); temp.venue_class_capacity=rst.getInt("venue_class_capacity"); temp.venue_exam_capacity=rst.getInt("venue_exam_capacity"); temp.venue_faculty_id=rst.getInt("venue_faculty_id"); this.add(temp); temp=null; } } catch(SQLException ex) {ex.printStackTrace(); } }} class periods extends ArrayList {}
class days extends ArrayList {}
what do you think about this???????
i am not too clear about the referencing of the course to a particular venue????
Just a style thing that may save you later: always start classes with uppercase and variables with lowercase. The reason is that then you can say things like Item item = new Item(); and be clear that Item is the class and item is an instance of that class. You don't have to do this, but I find it easier. Otherwise, you get code like item itemObj = new item();, which I guess some people like.
A few things about the one you fleshed out. I put comments in the code.
CODE
// if you can, strict type the ArrayList, e.g. ArrayList<E> it will make life easier // I renamed classes venue and venues. class VenueCollection extends ArrayList<Venue> { public venues() { Connection conn=null; String sql = "select" + " venue_id,venue_name,venue_location,venue_class_capacity,venue_exam_capacity,venu e_faculty_id" + " from venue" ); try { conn = database.createconnection(); Statement stat= conn.createStatement(); ResultSet rst= stat.executeQuery(sql); while(rst.next()) { // must create a new instance of venue, // otherwise you're loading the same one over and over. Venue temp = new Venue(); temp.venue_id=rst.getInt("venue_id"); temp.venue_class_capacity=rst.getInt("venue_name"); temp.venue_name=rst.getString("venue_name"); temp.venue_location=rst.getString("venue_location"); temp.venue_class_capacity=rst.getInt("venue_class_capacity"); temp.venue_exam_capacity=rst.getInt("venue_exam_capacity"); temp.venue_faculty_id=rst.getInt("venue_faculty_id"); this.add(temp); } } catch(SQLException ex) { ex.printStackTrace(); } finally { // no matter what, close that open connection. if (conn != null) try { conn.close (); } catch (Exception ex) {} } } }
this is the code that i have written for timetable class. it uses an array of lectures. every lecture has various attributes and these are loaded from the database. i am yet to modify the connection statements so i can close the connection . i will work on that.
CODE
/* * cell.java * * Created on Jan 24, 2008, 3:28:28 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */
package naak_task_scheduler;
import java.sql.*; import java.util.*;
/** * * @author Nuku */ public class TimeTable extends ArrayList<Lecture> {
ResultSet rst;
public TimeTable() { try { rst=TimeTable.executequerry("select * from tt_data");
} } class PeriodCollection extends ArrayList<Period> { ResultSet rst;
public PeriodCollection() { try { rst=TimeTable.executequerry("select * from periods order by period_id"); while(rst.next()) { Period temp=new Period(); temp.period_id=rst.getInt("period_id"); temp.period_start_time=rst.getTime("start"); temp.period_end_time=rst.getTime("end"); // temp.period=rst.getString("period"); this.add(temp);
class DayCollection extends ArrayList<Day> { ResultSet rst; public DayCollection() { try { rst=TimeTable.executequerry("select * from day order by day_id"); while(rst.next()) { Day temp=new Day(); temp.day_id=rst.getInt("day_id"); temp.day_short_name=rst.getString("day_short_name"); temp.day_long_name=rst.getString("day_long_name"); this.add(temp);
thanks, thanks , thanks!!!!! for your insightful and helpful tips .its really giving me a much broader picture of how i can write the code in a more simpler,accurate and understandable manner. i havent written out the course arraylist yet but i have a question for you. wouldent your search for a particular record in the arraylist collection be inefficient since you would have to go iteratively through the whole arraylist one by one before you can come to the record you are looking for????wouldent this reduce the efficieny and speed of the application drasticallly???? lets say for eg... you have 10000 venues and you have a referece table which is asking for a partcular attribute of a particular field and that field happens to be a column on the 9999 record wouldnt that reduce the speed of your code???? i am looking for a way where you can access each element in the arraylist using the key??? especially where for every period and day you can have a sub array which you can iterate through to find all the venues and the courses taking place at those venues. i was thinking a bout using the ids of the records as the keys for each member of the arraylist ??????? what do you think???? about the code that i have written and also about the questions that i asked???
wouldent your search for a particular record in the arraylist collection be inefficient since you would have to go iteratively through the whole arraylist one by one before you can come to the record you are looking for????wouldent this reduce the efficieny and speed of the application drasticallly????
Yep! Good catch. This is the kind of thing people are talking about when they say "scalability".
Right now you're grabbing every possible record for the table. For pick lists and small, non dynamic data you'll do that. However, most times you'll put some limitation on how much data you bring back. Sometimes you'll even put a hard cap on the records retrieved. Think about how web sites present data to you; one page at a time.
The other thing you're doing is making your collection of objects know too much. Ideally, the object holding the data doesn't know about databases, or flat files, or XML, it just represents information in memory.
protected String getFillSql() { return "select a.period_id, a.start, a.end from periods a"; }
public int fillById(List dataItems, int periodId) throws SQLException { PreparedStatement stmt = this.getConnection().prepareStatement( getFillSql() + " WHERE a.period_id=?" ); stmt.setInt(1, periodId); return this.fill(dataItems, stmt.executeQuery()); } }
class PeriodCollection extends ArrayList<Period> { }
PeriodCollectionDataAdapter da = new PeriodCollectionDataAdapter(); PeriodCollection list = new PeriodCollection(); da.fill(list); da.fillById(list,1);
If you're paying attention, there's a lot of code missing there. That's because Object Oriented design allows you to throw all the repetative stuff into the parent. The art is finding the repetition.
CODE
public abstract class DataAdapterBase { private Connection conn = null;
public int fill(List dataItems) throws SQLException { return this.fill(dataItems, getFillResultSet()); }
}
// and, for your application abstract class ApplicationDataAdapterBase extends DataAdapterBase { protected Connection createNewConnection() { return database.createconnection(); } }
I hope I'm not throwing to much code at you.
One of the reasons for all this code, that you don't have, is that you're avoiding a major issue in your public static ResultSet executequerry(String querry). Well, you're ignoring the issue. You NEED to close your database connection. If you want to play real nice, you should also close your ResultSet. That method just gets a connection and carries on. Best case is it's maintaining a shared connection, or is an alias to a connection pool, but it's still troubling. If it is an always open connection ( bad idea ), then you must clean up those open ResultSets.
i am looking for a way where you can access each element in the arraylist using the key???
The brute force method would be to loop through the entire thing and give it back if you find it. One solution would be to keep a HashTable of all the keys and the respective index they map to. The disadvantage is that you must keep each in sync.
Ideally, you'd want constructors for you objects that require what you consider the primary key. Here's an example.
CODE
class Period { // period_id is our key, don't screw with it private int period_id; public Time period_start_time; public Time period_end_time; public String period; public Period(int period_id) { this.period_id = period_id;
} // ideally, all object will have getter and setter methods // and no public variables public int getPeriodId() { return period_id; }
public boolean equals(Object obj) { if (obj==null) { return false; } if (obj.getClass() != this.getClass()) { return false; } return (this.period_id==((Period)obj).period_id); }
// lazy hashCode, should work fine public int hashCode() { return (this.period_id+"~").hashCode(); } }
Try throwing this in a array list, with a bunch of friends. Then, ask for list.get(list.indexOf(new Period(5))); or something and see if that you get the one where period_id=5.