I got a task for a Season Object which can only save doubledigit integer numbers as the season number.
How can I initialize the value properly so it will only store doubledigit numbers?
I'm not allowed to use methods or my constructor for that.
the only possible solution I found (even though it would be dumb) is to use an enum from 1 to 99.
Is this really the solution? I'm also not allowed to use API classes for that.
Edit:
public class Season {
String name;
Series series;
int seasonNumber;
public Season () { }
}
I didn't post the code on purpose cause it isn't anything that will help
Edit2: (Tl;Dr of the Task)
The Task is to create a Series, Season and Episode Object. Series and Episode aren't of interest as for this question. The Season Object is defined as you can see in the code above.
The overall conditions are as following:
- primitive datatypes, String, enum are allowed and every class I wrote myself.
- no API classes are allowed.
- methods aren't needed.
- constructor isn't allowed to modify my number with regEx or anything like that
This is the best solution I can come up with:
public Season(int seasonNumber) {
if (seasonNumber < 1 || seasonNumber > 99) {
throw new IllegalArgumentException("Value between 1 and 99 (both inclusive) required. Found + " seasonNumber);
}
this.seasonNumber = seasonNumber;
}
I am not using a method, because the logic is all in the constructor. Though I suspect the person who gave you this hasn't got his point across with the assignment texts.
If you want the season number returned as 01, 02, etc., you could create a method that returns a String, instead of an int:
public String getSeasonNumber() {
if (seasonNumber < 10) {
return "0" + seasonNumber;
} else {
return seasonNumber;
}
}
Related
this is my first question on here and I did a search before forming it, so I hope everything is as required.
I am working on a school assignment in Java. I am able to produce the required output but there are a lot of null instances created first. I don't understand why. Information about the library the professor created for the course and the code are below
Library included with this course: i2c.jar. It can be found here.
included in this Library are the classes Country and CountryDB. The API for the Country class can be found at http://130.63.94.24/~roumani/book/doc/i2c/ca/roumani/i2c/Country.html
The API for the CountryDB class can be found at http://130.63.94.24/~roumani/book/doc/i2c/ca/roumani/i2c/CountryDB.html
I am asked to create a class called Game, using the Country and CountryDB APIs.
The only attribute is db, which is an instance of CountryDB.
The constructor only sets the attribute (db) for this instance to a new CountryDB object.
The class is also meant to include a method (called qa) that follows this pseudocode:
get a reference to the database's capital city list
determine the size of this list. Cal it n.
generate a random number in [0,n) called index.
invoke get(index) on the list to get a random capital city. Call it c
get a reference to the database's data map
invoke get(c) on the map to get a reference to a country. Call it ref.
The method is then supposed to return one of two Strings (which will be clear in the code). Everything works as it should, except I get a lot of "nulls" before the desired output. When made into a List, db has size 241 so I suspect I am creating 241 null instances and 1 proper instance. I have no idea why though. I have tested every line of code in my method and the constructor was dictated by the textbook.
CODE
package ca.yorku.eecs.caps;
import java.util.List;
import java.util.Map;
import ca.roumani.i2c.Country;
import ca.roumani.i2c.CountryDB;
public class Game
{
private CountryDB db;
public Game()
{
this.db = new CountryDB();
}
public String qa()
{
List<String> capitals = db.getCapitals();
System.out.println(capitals.toString());
int n = capitals.size();
System.out.println(n);
int index = ((int) (n * Math.random()));
System.out.println(index);
String c = capitals.get(index);
System.out.println(c);
Map<String, Country> data = db.getData();
Country ref = data.get(c);
if (Math.random() > 0.5)
{
return "What is the capital of " + ref.getName() + "? \n" + ref.getCapital();
}
else
{
return ref.getCapital() + " is the capital of? \n" + ref.getName();
}
}
public static void main(String[] args)
{
Game g = new Game();
System.out.println(g.qa());
}
}
the System.out.println() statements are only there to test when the nulls occur. It clearly happens immediately because my psvm output is 241 nulls (on separate lines) followed by my desired output. Can somebody please tell me what I am doing wrong?
And, more generally (to help more people) how do you implement classes, the constructor of which instantiates another class and sets it as an attribute value?
I appreciate any help. Also, please note, I am not trying to get others to do my work for me. I've spent hours on this and my lab TA also wasn't sure why it happens either. He would have helped me correct it had he known how.
Thank you.
My lecturer started to refer to something called guardian code in our reading material. In case it helps, this is a Java beginners module. Here are some references to in the text.
Since there are no mutators and therefore no mutator guardian code the guardian code is forced into the constructor (as a call to the validateDate(…) private helper method). The constructor would usually call the mutators to check initial values received as constructor parameters were valid before assigning them their respective instance variables.
Any help would be greatly appreciated
Thanks!!
The text refers to code that provides parameter validation, "guarding" the object from entering a bad state.
Fox example, if you are building a class with a String property called serialNumber that must be seven to nine characters long, you would add a setter like this:
void setSerialNumber(String sn) {
if (sn == null || sn.length() < 7 || sn.length() > 9) {
throw new IllegalArgumentException("sn");
}
serialNumber = sn;
}
if in the code snippet above is "guardian code". The textbook says that when the class is mutable, this guardian code goes into setters. However, when the class is immutable, you move this code into the constructor:
MyObject(String sn) {
if (sn == null || sn.length() < 7 || sn.length() > 9) {
throw new IllegalArgumentException("sn");
}
serialNumber = sn;
}
Your lecturer likely meant guard code. This adds an extra defensive layer of validation to ensure that the data you're either receiving or sending off is not invalid in any way. In general, one writes guard code to ensure that a value that they require isn't null (to prevent NullPointerExceptions), or is within an expected range - although that's a broader discussion on validation.
As an example, if I were writing a method called boolean validateDate(Date date), one piece of guard code I'd write is:
public boolean validateDate(Date date) {
if(null == date) {
throw new IllegalArgumentException("Date can't be null");
}
// other logic to follow
}
I need the data that caused the rule to be fired from the "When" section in the "Then" section of the rule. For instance, if I wanted to make note of all bad apples in a store if there were more than 50, this is how I'm doing it.
Rule "Detect Bad Apples"
When
s : Store( numberOfBadApples() > 50 )
Then
// Print out a list of the bad apples
To make it a little more complicated I have multiple rules that will overwrite. Otherwise, I would store the data into a variable in the Store class.
Is there a better way to do this? I've been reading through the Drools 6.2 Documentation, but I'm still confused.
---EDIT----
The Store Class in Java would look like:
public class Store {
private ArrayList<Apple> appleList;
// The appleList would be filled in another method
public int numberOfBadApples() {
int badAppleCount = 0;
for (Apple apple : appleList) {
if (apple.isBad()) {
badAppleCount++;
}
}
return badAppleCount;
}
}
So in the "Then" statement in Drools, I want to return a list of the apples (the bad ones, in this case) that caused the rule to be fired.
I have written a method with the aim to count the number of times a specific flavour of crisps appears in a snack machine in blueJ
public int countPacks(String flavour){
int n = 0;
int nrFlavour = 0;
while( n < packets.size()) {
if( packets.get(n).equals(flavour)){
nrFlavour++;
n++;
}
else n++;
}
return nrFlavour;
}
I have an Arraylist 'packets' which holds PackOfCrisps objects which have a specific flavour. However when I have added say three packets of "salt" flavour crisps and I run this method, inputting "salt" as the flavour, it just returns 0 as though there are no PackOfCrisps objects with flavour "salt".
Sorry if this doesn't make sense. I am very new to Java and I have tried to explain my problem the best I can. :)
The list packets holds PackOfCrisps objects, and the method takes a String parameter. So the statement packets.get(n).equals(flavour) is comparing a PackOfCrisps object to a String, hence the count variable will never increase.
You need to compare the flavour string to the specific field of the object, something like:
if(packets.get(n).getFlavour().equals(flavour)){
On a side note, you can replace the while loop with a simple for loop and remove the increment of n.
There is a built-in solution to your problem, you can use this method
You can rewrite your countPacks method like this :
public int countPacks(String flavour){
return Collections.frequency(packets, flavour);
}
This is a simplified example. I have this enum declaration as follows:
public enum ELogLevel {
None,
Debug,
Info,
Error
}
I have this code in another class:
if ((CLog._logLevel == ELogLevel.Info) || (CLog._logLevel == ELogLevel.Debug) || (CLog._logLevel == ELogLevel.Error)) {
System.out.println(formatMessage(message));
}
My question is if there is a way to shorten the test. Ideally i would like somethign to the tune of (this is borrowed from Pascal/Delphi):
if (CLog._logLevel in [ELogLevel.Info, ELogLevel.Debug, ELogLevel.Error])
Instead of the long list of comparisons. Is there such a thing in Java, or maybe a way to achieve it? I am using a trivial example, my intention is to find out if there is a pattern so I can do these types of tests with enum value lists of many more elements.
EDIT: It looks like EnumSet is the closest thing to what I want. The Naïve way of implementing it is via something like:
if (EnumSet.of(ELogLevel.Info, ELogLevel.Debug, ELogLevel.Error).contains(CLog._logLevel))
But under benchmarking, this performs two orders of magnitude slower than the long if/then statement, I guess because the EnumSet is being instantiated every time it runs. This is a problem only for code that runs very often, and even then it's a very minor problem, since over 100M iterations we are talking about 7ms vs 450ms on my box; a very minimal amount of time either way.
What I settled on for code that runs very often is to pre-instantiate the EnumSet in a static variable, and use that instance in the loop, which cuts down the runtime back down to a much more palatable 9ms over 100M iterations.
So it looks like we have a winner! Thanks guys for your quick replies.
what you want is an enum set
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumSet.html
put the elements you want to test for in the set, and then use the Set method contains().
import java.util.EnumSet;
public class EnumSetExample
{
enum Level { NONE, DEBUG, INFO, ERROR };
public static void main(String[] args)
{
EnumSet<Level> subset = EnumSet.of(Level.DEBUG, Level.INFO);
for(Level currentLevel : EnumSet.allOf(Level.class))
{
if (subset.contains(currentLevel))
{
System.out.println("we have " + currentLevel.toString());
}
else
{
System.out.println("we don't have " + currentLevel.toString());
}
}
}
}
There's no way to do it concisely in Java. The closest you can come is to dump the values in a set and call contains(). An EnumSet is probably most efficient in your case. You can shorted the set initialization a little using the double brace idiom, though this has the drawback of creating a new inner class each time you use it, and hence increases the memory usage slightly.
In general, logging levels are implemented as integers:
public static int LEVEL_NONE = 0;
public static int LEVEL_DEBUG = 1;
public static int LEVEL_INFO = 2;
public static int LEVEL_ERROR = 3;
and then you can test for severity using simple comparisons:
if (Clog._loglevel >= LEVEL_DEBUG) {
// log
}
You could use a list of required levels, ie:
List<ELogLevel> levels = Lists.newArrayList(ELogLevel.Info,
ELogLevel.Debug, ELogLevel.Error);
if (levels.contains(CLog._logLevel)) {
//
}