Should I initialize object values? - java

The question may sound a bit silly, but should an object class look something like this:
class Book {
String title;
int year;
///so on and so forward
}
or should it look like this?
class Book {
String title = "";
int year = 0;
///so on and so forward
}
i understand that actual values should be set by the constructor (or setValue methods), but should the initial values be null, or 0/"" ?
Edit: Im trying to work with the object values as strings (replacing certain characters, etc), which doesnt work if the value is null; i wasnt sure if i should add an "if" clause or simply initialize values to an empty string

It should look something like this:
public class Book {
private String title;
private int year;
}
public Book(String titleIn, int yearIn) {
title = titleIn;
year = yearIn;
}
And the way you should create the object is:
Book harryPotter = new Book("Harry Potter", 2014);

Related

How do I add an item from a class to an ArrayList?

I know the question seems weird, but I'll try to explain it the best that I can. I am doing an Amusement Park Project where you have methods for the tickets, merchandise, etc. I made a Ticket class with the methods, but now I'm in the AmusementPark class trying to create a method of taking the date from that class and putting it into a new ArrayList. Maybe my code will help explain it.
First, here is my Ticket class......
import java.text.DecimalFormat;
public class Ticket {
private long number;
private String category;
private String holder;
private String date;
private double price;
private boolean purchased;
Ticket(long num, String cat, String h, String dt, double pr, boolean pch){
this.number= num;
this.category= cat;
this.holder= h;
this.date= dt;
this.price= pr;
this.purchased= pch;
}
long getNumber(){
return number;
}
String getCategory(){
return category;
}
String getHolder(){
return holder;
}
String getDate(){
return date;
}
boolean getPurchased(){
return purchased;
}
double getPrice(){
return price;
}
void setPrice(double pr){
price= pr;
}
void setChangePurchased(boolean newStatus){
purchased= newStatus;
}
#Override
public String toString(){
DecimalFormat dm= new DecimalFormat("#.##");
String disp;
disp = "Number: " + getNumber() + "\nCategory: " + getCategory() + "\nTicket Holder Name: " + getHolder() + "\nDate: " + getDate()
+ "\nPrice: " + dm.format(getPrice()) + "\nPuchased Completed?: " + purchased;
return disp;
}
}
Here is some of the Pseudo Code explaining what I am trying to do with the next class I'm about to post.
Create an ArrayList from the Ticket class.
//The ticket class has the following constructors....
// (Ticket number of type long, category of type String, Ticket holder of type String, Date of admission, purchase price of type double, variable named "purchased" whether the ticket has been paid for of type boolean)
//One of the variables of type class is tickets in which the ticket class is made into an ArrayList.
//The next task is to get tickets for dates where they are available, which is done by searching tickets where the purchase is not completed.
Create a public ArrayList<Date> method called getTicketDates(){
Create a variable called theDateArray which is a new ArrayList<Date>;
For(starting at the first position of the list, go through the the entire list incrementing by one){
if (boolean purchased of the Ticket ArrayList is false)**{
Add the date of the object from the Ticket ArrayList to theDateArray ArrayList.}** //This stores the dates of all tickets not yet purchased into the new ArrayList.
}
Return theDateArray;
}
//The next task is to search through theDateArray for only select dates and post the available tickets for that date as an integer.
Create a method which displays the number of tickets for a specified date by going through theDateArray (Date date) {
For(starting at the first position of theDateArray, go through the entire list and look for tickets that have a particular date){
if (the date== entered date){
Include the ticket as one of the tickets available for that date.
}
}
Return the total number of tickets available for that date as a type integer.
}
Okay, now here is my AmusementPark class. Note It is not finished. I'm just trying to get this one part done....
import java.util.ArrayList;
import java.util.Date;
public class AmusementPark {
private ArrayList<Ticket> tickets;
private ArrayList<Merchandise> merchandise;
private String name;
AmusementPark(String name){
this.name=name;
this.tickets = new ArrayList<Ticket>();
this.merchandise= new ArrayList<Merchandise>();
}
String getName(){
return name;
}
public ArrayList<String> getTicketDates(){
ArrayList<String> theDateArray= new ArrayList<>();
int i;
String date = Ticket.getDate(); //This is not working. See Reason Below.
for (i=0; i<tickets.size(); i++){
if(tickets.get(i).getPurchased()== false){
theDateArray.add(date);
}
}return theDateArray;
}
}
Okay, so now what happens when I try to call the method of getDate() from the Ticket class, it's not allowing me to use it for the reason that I cannot make a static reference to a non-static method. However, when I try to make the method static, it messes up the other class by saying I cannot make a static reference to a non-static field.
An ArrayList of the Ticket class has already been made. I need it to scroll through that list, get the ones where the boolean is false, and add the date to the next ArrayList.
Does this at all make sense?
Any ideas that would be better?
Let's take your method.
public ArrayList<String> getTicketDates(){
ArrayList<String> theDateArray= new ArrayList<>();
int i;
String date = Ticket.getDate(); //This is not working. See Reason Below.
for (i=0; i<tickets.size(); i++){
if(tickets.get(i).getPurchased()== false){
theDateArray.add(date);
}
}
return theDateArray;
}
Notice the problem on the Ticket.getDate() that you try to do whithout an instance, so a static call. But what you explain, you want the date for the Ticket of the list tickets. Good, you are iterating it after but are pushing this strange value date coming from a "static method".
You problem is that the instance holding the date you want is in the list. You are using it to see if it is purchased or not. So call the method on those instance to get the value :
for (i=0; i<tickets.size(); i++){
if(tickets.get(i).getPurchased()== false){
theDateArray.add(tickets.get(i).getDate());
}
}
But better :
Ticket ticket;
for (i=0; i<tickets.size(); i++){
ticket = tickets.get(i);
if(ticket.getPurchased()== false){
theDateArray.add(ticket.getDate());
}
}
If I understand it correctly what is required here is to extract dates for not purchased tickets into separate dates array. And you already got it correctly in your pseudocode, you just need to follow it more strictly during implementation:
public ArrayList<String> getTicketDates() {
ArrayList<String> theDateArray = new ArrayList<>();
// iterate over all tickets
for ( Ticket ticket : tickets ) {
// if ticket not purchased
if ( ! ticket.getPurchased() ) {
// add ticket's date into array
theDateArray.add( ticket.getDate() );
}
}
return theDateArray;
}
DON'T MAKE STATIC REFERENCE !Instead of writing a what's code answer let's focus on the workaround of problem.
Whenver you will set values to instance variables of TICKET Class it will refer to a particular object (new ticket()) to access its values if you make variables of class staticValues will be stored when class is loaded and not when object is created but arraylist items need to have
Object of ticket Class.
A simple approach should be
ASSIGN THE VALUES TO VARIABLES WHEN EVER YOU MAKE AN OBJECT OF TICKET CLASS BY BY PASSING VALUES IN ITS CONSTRUCTOR AND THEN
ADD THOSE OBJECTS TO ARRAYLISTITEMS
ticket class
public class Ticket {
private long number;
private String category;
private String holder;
private String date;
private double price;
private boolean purchased;
Ticket(long num, String cat, String h, String dt, double pr, boolean pch){
this.number= num;
this.category= cat;
this.holder= h;
this.date= dt;
this.price= pr;
this.purchased= pch;
}
make a new object and pass values
Ticket t1=new Ticket(3,"yourstring","yourstring",yourDouble,true/false);
add items in arrayliSt:
List<Tickets> tList=new ArrayList();
tList.add(t1);
tList.add(t2);
//and so on
now retrive values from arralylist
Ticket t=tlist.get(0);
t.cat;
t.whatevrbe thevalue be

Dynamically Generate enum values

I have been looking around for a good example on how I might go about dynamically generating enum values. I found a couple good articles, however I am looking for a compile time solution and what I've found is only at run time.
Does anyone know if this is even possible? I have yet to find anything that hints it might be.
Thanks!
EDIT:
For clarification: I would like to be able to read values out of a database and populate an enum with those values.
In a perfect world, I would like my enum class to look like the following:
public static enum STATE {
/* populated from DB if possible */
MA("high taxes", 6),
NH("low taxes", 3),
...
...
private String desc;
private in rating;
public STATE (String description, int rating) {
this.desc = description;
this.rating = rating;
}
}
Well, here is an approach that does it on class initialization. Which is runtime:
public enum States {
MA, NH; // ...
private String description = "Description of " + name() + " not found in database.";
private int rating;
// Static initialization is performed after the enum constants
// are initialized, but can still change *non-final* fields
// in the constants
static {
String sql = "SELECT abbreviation, description, rating "
+"FROM states "
+"WHERE abbreviation IS NOT NULL ";
ResultSet rs;
// Open connection, create statement, execute, retrieve
// result set. IMPORTANT: catch and properly handle all
// checked exceptions, or else you'll get a nasty
// initialization error. OTOH, you may not want your
// application to start if this fails.
while ( rs.next() ) {
String abbreviation = rs.getString(1);
String description = rs.getString(2);
int rating = rs.getInt(3);
States st;
try {
// Get the enum constant that matches the abbreviation.
st = valueOf(abbreviation);
// Set the values in that constant
st.description = description;
st.rating = rating;
} catch ( IllegalArgumentException e ) {
// This exception happens when the abbreviation
// doesn't match any constant. If you don't put
// anything here, such values will be silently
// ignored. If you don't catch, such values will
// throw an initialization Error.
}
}
// Clean up all database-related stuff.
}
// Only getters, no setters, as values are all
// set from database in the static initialization.
public String getDescription() {
return description;
}
public int getRating() {
return rating;
}
}
With this definition, you can use the enum constants in your program, and the values in the description and rating field will be loaded at class initialization from database. Note that I gave a default value to description which will show up if the particular state's abbreviation is not in the database.
But as I said, this is run time. Although not completely impossible, I can see no sense in loading the values from database at compile time, as these values will stay fixed when you use your resulting .class file or jar. When you change values in your database, the values seen by the application will still be the one hard-compiled into the enum. In fact, you won't even need the database to be up to run the application.
But if you insist on doing this for some reason, well, no IDE will support this directly, I suppose. But you could probably write a script that manipulates the text of your enum java file, and use that script in a pre-compile phase in your build tool (maven, ant...). You'll probably need to write your class much like the above, only with the static initializing block empty. You'll need a clean copy outside of your src directory, and run the script so that it fills up the static initialization block with text derived from the database, and writes the result inside your src directory.
In short: not recommended, system/tool dependent, not useful, but also not impossible.
You can use a class for this at the exact same place where you would have put the enum and get similar behaviour:
public final class STATE {
public static final STATE MA;
static {
// SELECT desc, rating FROM myTable where name = 'MA' ... or what suits you
...
MA = new STATE(myDesc, myRating);
}
...
private String desc;
private int rating;
private STATE (String description, int rating) {
this.desc = description;
this.rating = rating;
}
public String getDesc() {
return desc;
}
...
}
Because of the private constructor and because the class is final and only has getters you can only assign the predefined values to STATE. This means you can compare a STATE variable v just like that v == STATE.MA because they all use the same reference.
If you have fixed names, but the "values" are loaded from the database, you can use an enum constructor:
public enum Data {
A("a"), B("b"), C("c");
SomeType someName;
public Data(String s) {
someName = MyDatabase.loadValue(s);
}
public SomeType getSomething() {
return someName;
}
}
The constructor is called at class initialization.

How can I initialize an Object when one of the parameters is TBD

This is related to a Java homework assignment.
I've written a class for creating instances of Course Objects, each course has parameters like course name, max number of students and a room number. However for some of the classes the room is not known. Is there a way to initialize and a Course Object without the room number?
public class ITECCourse {
private String name;
private int code;
private ArrayList<String> students;
private int maxStudents;
private int room = 0;
. . .
//Constructor
public ITECCourse(String courseName, int courseCode, int courseMaxStudents, int room) {
this.name = courseName;
this.code = courseCode;
this.students = new ArrayList<String>();
this.maxStudents = courseMaxStudents;
this.room = room;
You have a few options:
You could create a second constructor that does not take a room number:
public ITECCourse(String courseName, int courseCode, int courseMaxStudents)
You could change room from and int to an Integer. This would allow a null value.
Either way, you'd want to add a method setRoomNumber() to allow the user to provide that value later.
Yes, you can overload the constructor. As well as the constructor that you have above you can add a new one to the class that would look like this:
public ITECCourse(String courseName, int courseCode, int courseMaxStudents) {
this(courseName, courseCode, courseMaxStudents, 0);
}
This would then allow you to not have the room default to a certain value in the case that it has not been set.
Another good thing about doing it this way is that by calling the other already existing constructor you're not running into the issue of repeating code everywhere (to set all the values).
See this question for more details on best practices
Add a second constructor that doesn't take (or set) the room number.

How to insert two item which are String and Drawable in a single line of Hashmap?

I have an issue here. I want to put a string and a drawable in a single hashmap. Since I'm really new to java, I'm not familiar with java syntax and declaration and I don't how to find the solution regarding my problem in the internet, that's why I come here. Basically my code looks like below:
private static String getAvModeText(String mode){
String avMode = mContext.getString(R.string.AVM_stand);
HashMap<String,String> mapAvM = new HashMap<String,String>();
mapAvMode.put(TvFunctionID.AVM.AVM_STANDARD, mContext.getString(R.string.AVM_stand));
mapAvMode.put(TvFunctionID.AVM.AVM_MOVIE, mContext.getString(R.string.AVM_mov));
mapAvMode.put(TvFunctionID.AVM.AVM_MOVIE_THX,mContext.getString(R.string.AVM_movTHX));
mapAvMode.put(TvFunctionID.AVMode.AVM_GAME, mContext.getString(R.string.AVM_game));
mapAvMode.put(TvFunctionID.AVM.AVM_PC, mContext.getString(R.string.AVM_PC));
mapAvMode.put(TvFunctionID.AVM.AVM_CUSTOM, mContext.getString(R.string.AVM_user));
mapAvMode.put(TvFunctionID.AVM.AVM_DYNAMIC, mContext.getString(R.string.AVM_dyn));
mapAvMode.put(TvFunctionID.AVM.AVM_DYNAMIC_FIXED, mContext.getString(R.string.AVM_dynFix));
if(mapAvMode.containsKey(mode)) {
avMode = mapAvMode.get(mode);
}
return avMode;
}
I want to make my code looks like this:
mapAvMode.put(TvFunctionID.AVM.AVM_MOVIE_THX,mContext.getString(R.string.AVM_movTHX + " " + R.drawable.ic_launcher));
But if I make it like this, there is an error and the error is at the getString() which is:
The method getString(int) in the type Context is not applicable for the arguments (String)
So if anyone know how to solve this, I really appreciate your help. Thanks.
Create class like
public class Video {
public final int title;
public final int drawable;
public Video(int title, int drawable) {
this.title = title;
this.drawable = drawable;
}
}
then create map with <String, Video> generic type
Map<String,Video> mapAvM = new HashMap<String,Video>();
I understand what you'd like to do and unfortunately HashMap in Java doesn't work that way. Basically the first parameter is the key and the second is the value. So you should do something like this.
HashMap<String, Drawable> mapAvM = new HashMap<String,Drawable>();
mapAvMode.put(TvFunctionID.AVM.AVM_STANDARD, mContext.getDrawable(R.drawable.ic_launcher));
Then if you need to access the drawable later on, you can call:
mapAvM.get(TvFunctionID.AVM.AVM_STANDARD);
which will return your drawable.

initializing an object in an array

I've been playing around with arrays for some time and this problem has been troubling me.
I created a user defined object and declared it in an array like this: `Property regesteredAssets[] = new Property[200];
And here's my constructor: `
public Property(String newPropertyName,String newPropertyAddress,String newPropertyType, String newPropertyDescription)
{
propertyName[arraySequence] = newPropertyName;
propertyFullAddress[arraySequence] = newPropertyAddress;
propertyType[arraySequence] = newPropertyType;
propertyDescription[arraySequence] = newPropertyDescription;
arraySequence++;
}
I want to initialize each array regesteredAsssets[] according to my desire. How can I do it?
Do I have to use arrays in my attributes in the Property class too?
You do not need your attributes to be arrays, unless a particular asset has multiple of something. In this case, I don't think it does. You can greatly simplify your code as follows:
public class Property {
private String name, address, type, description;
public Property(String name, String address, String type, String description) {
this.name = name;
this.address = address;
this.type = type;
this.description = description;
}
public static void main(String[] args) {
Property[] registeredAssets = new Property[200];
registeredAssets[0] = new Property("Joe Bloggs", "555 Fake St.", "IMPORTANT", "Lorem Ipsum Dolor");
// etc.
}
}
If you have an array of type Property, you can set each of the elements up using the following code:
regesteredAssets[0] = new Property( enterYourParametersHere );
I assume the fields in your Property constructor are single fields, and therefore you do not need to set them using the array notation field[index] = value, and indeed, if the Property class is of the consistency I think it is, then this will produce a compilation error.
If you wanted to set up multiple entries in your array, you could perform the initialisation step inside a loop, providing a loop index to the index of the array as below:
for( int i = 0; i < 10; i++ )
{
regesteredAssets[i] = new Property( enterYourParametersHere );
}
I hope this helps...

Categories

Resources