I am new to programming/Java and have been trying to teach myself it the last couple of weeks using some free textbooks and online resources. I thought a good way to learn would be to build a role-laying game I enjoy into a Java program. That being said, I know lots of people don't document their code effectively and want to avoid this being a habit, so I am trying to document everything in as much detail as possible. I cannot figure out if I am documenting this correctly though, even when referencing the Javadoc page, so any help would be appreciated. Basically I have a class 'Character' which implements all the required aspects of a character in this game. As an examplle, I have an enum which is a list of possible ability scores for a character in the game:
/**
* AbilityScores is an enum type containing all the possible ability scores in the game. It is
* utilized by the HashMap {#link #abilities} for the keys with an int being used as the values.
*/
private enum AbilityScores {
STRENGTH,
DEXTERITY,
CONSTITUTION,
INTELLIGENCE,
WISDOM,
CHARISMA,
INSPIRATION,
ARMOURCLASS
}
Then I have the corresponding HashMap:
/**
* abilities is a {#link HashMap} collection that contains {#link AbilityScores} as
* keys and {#link Integer} as values.
*/
private HashMap<AbilityScores, Integer> abilities = new HashMap<AbilityScores, Integer>();
And then here is an example of my accessor method for a character's strength:
/**
* This method returns a character's strength in the form of an integer.
* #return strength as an integer.
*/
public int getStrength() {
return abilities.get(AbilityScores.STRENGTH);
}
Am I documenting this correctly or have I incorrectly used '#link' etc. I did find some examples but I wasn't 100% sure as I couldn't find an example (apologies if there is one) where it showed an entire one start to finish like this one.
Any input or guidance is appreciated!
Thank you
Related
I'm teaching myself Java and was hoping for feedback regarding this question:
Write a Java interface with two methods, one that adds two doubles together returning the sum and one that multiplies two doubles together returning the product. Use JavaDoc comments.
Am I missing anything? Is it appropriate to include #return in the JavaDoc comment for the interface?
/**
* This is an interface for basic math.
*/
public interface Math {
/**
* This method will be used to add two doubles.
* #param a a value to be added
* #param b the other value to be added
* #return the sum of the two doubles
*/
public double add(double a, double b);
/**
* This method will be used to multiply two doubles.
* #param a a value
* #param b the other value
* #return the product of the two doubles
*/
public double multiply(double a, double b);
}
Am I missing anything?
There is nothing fundamentally wrong or "missing" from the javadocs in their current form.
Is it appropriate to include #return in the JavaDoc comment for the interface?
It is absolutely appropriate. An interface is a form of API, and meaning of the value returned by an API method is a fundamental aspect of the interface. If the meaning of a method return value is not specified in an interface then a caller of the interface method can't know what to expect. This makes programming to the interface difficult.
Yes, it is appropriate to have #return.
Few things you can improve:
To follow Java coding conventions, start method names with lowercase
(e.g. use add instead of Add).
Have better parameter names. E.g.
use number1, number2 instead of a, b.
Start #param and #return descriptions with uppercase letters (e.g. #param number1 First number).
I thinks it is better to say Returns the addition of two given numbers than This method will be used to add two doubles.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
The continuation of the question.
I need to statically and publicly storage data as arrays but I don't want somebody to modify my data. I need only ability to read from those arrays. Therefore I think I should use something like constant arrays which are presented in C++.
As far as I understand Collections.unmodifiableList(Arrays.asList(...)) prevents from modify the list at run-time but not at compile-time.
I've made the following class (code is updated). I suppose I'm not reinventing the wheel because I cannot have the same result using unmodifiableList.
/**
* Emulates constant arrays from C++.
*
* #param <E> Type of elements. Has to be immutable type.
*/
public final class ConstArray<E> {
/** Stores elements. */
private final E[] storage;
/**
* Constructs the object.
*
* #param storage Elements.
*/
public ConstArray(final E[] storage) {
this.storage = storage.clone();
}
/**
* Returns element at {#code idx}.
*
* #param idx Index of returning element.
* #return Element at {#code idx}.
*/
public final E get(final int idx) {
return storage[idx];
}
}
The size method and some other methods are omitted.
I've tested the class and it works.
To paraphrase, if I provide my library and somebody try to modify my data, I think it's better when he/she will know immediately that it's not possible (my class doesn't have a method to modify anything) and if I used unmodifiableList he/she will notice only a crash of the program.
What are advantages and disadvantages of this class? Is there a way to improve this class?
UPD:
I decided to use #Hoopje 's advice (see answers). It's based on experience that I don't have: I'm only a Java beginner.
If "reinventing the wheel" is not disadvantage enough, I see one major disadvantage to your approach:
Arrays.asList and Collections.ummodifiableList return List instances, so they are integrated in the Java Collections framework. This means that you can easily use them in enhanced for loops (for (E item : list) { }), as streams (list.stream()), use all List methods, pass them to methods which expect Collection or List subclasses, etc.
A minor point is that your class makes a copy of the array, whereas both Arrays.asList and Collections.ummodifiableList return views of their argument, so they do not copy the array.
By the way, creating a shallow copy of an array does not require "magic": you can do
this.storage = storage.clone();
Answer to UPD1:
Yes, it is unfortunate that Java does not provide interfaces for collections which cannot be modified. Thus, immutable List instances will have, for example, an add(E) method which simply throws an exception. So there is no compile-time guarantee for immutability.
However, in the Javadoc for your method you will of course write that the returned list is immutable. And if the user of your library tests his/her software, he will very deterministically see the exception and realize that he/she made a programming error.
And believe me, the users of your library will very much hate you if you take away their possibility to use the returned list in Collection-based APIs, just for the small advantage of not having any methods that look as if they would modify it.
I'm a little embarrassed to be asking this because I'm sure this is a very basic question but having searched and thought about it I still can't work this out.
The code is from a class the tutor walked through developing during a tutorial on collections for my course. The class represents a crime sheet of districts with associated crime codes. The sheet is implemented as a SortedMap where the keys are of type String (representing the district) and the values are an ArrayList of Integers (representing the crime codes).
There is one method that we didn't manage to finish during the tutorial that the tutor sent on a copy of and I can't follow the logic. The code for the method is below
/**
* displays districts affected by given crime code
*
* #param Integer crime code
* #return none
*/
public void displayAffectedDistricts(Integer crimeCode)
{
ArrayList<Integer> searchCode;
for(String eachDistrict: crimeTable.keySet())
{
searchCode = new ArrayList<Integer>();
searchCode.add(crimeCode);
if(!(searchCode.retainAll(crimeTable.get(eachDistrict))))
{
System.out.println("Code "+crimeCode+" found in district "+eachDistrict);
}
}
}
I've run the code and can see that this works but I can't follow the logic of the if condition.
My understanding is that searchCode.retainAll(crimeTable.get(eachDistrict)) will evaluate to the reference to the list searchCode and that, at that point, searchCode will contain the single value given by the crimeCode argument if the Map entry for eachDistrict has crimeCode in it's set of values or will otherwise be empty.
As far as I'm aware that's not a boolean value so can't be used as an if condition without a comparison operator.
Could someone please explain what I'm missing?
It's pretty bad code. But, here's how it works:
The retainAll() method returns true if the list changed because of the operation. A list is created that contains the target code, and if the other list contains it, the list will not change.
I would severely mark down the person who wrote this if I was marking it, because it's obtuse. Here's a better implementation, uses much less code, is straightforward and easy to understand and performs better too:
public void displayAffectedDistricts(Integer crimeCode) {
for (String eachDistrict : crimeTable.keySet()) {
if (crimeTable.get(eachDistrict).contains(crimeCode)) {
System.out.println("Code "+crimeCode+" found in district "+eachDistrict);
}
}
}
But even this can be improved upon, by using even less code and performs much better:
public void displayAffectedDistricts(Integer crimeCode) {
for (Map.Entry<String, ArrayList<Integer>> entry : crimeTable.entrySet()) {
if (entry.getValue().contains(crimeCode)) {
System.out.println("Code "+crimeCode+" found in district "+entry.getKey());
}
}
}
This last version avoids all the numerous calls to get(). It is the most elite way of coding it. Suggest this to your teacher, who by the way should find another job.
retainAll does return a boolean according to http://docs.oracle.com/javase/1.5.0/docs/api/java/util/AbstractCollection.html#retainAll(java.util.Collection)
retainAll returns true if this list changed as a result of the call.
So
!(searchCode.retainAll(crimeTable.get(eachDistrict)))
is equals to
crimeTable.get(eachDistrict).contains(crimeCode)
The javadoc of retainAll() says:
Returns:
true if this list changed as a result of the call
The method could also be designed to return the resulting list. However, this would obscure that the change was not performed on a copy, but the original list. Moreover, it is pretty handy to know if the set operation has caused a change.
retainAll is defined in java.util.List and return a boolean as return value. So this value can be used as the condition of the if statement.
I want that when i mouse over a method i would be able to see my documentation of what the method does like when i put the mouse over Java's method I know that /** */ is how its done but:
How do you explain what the Params Stands for?
How do you create a new line, or make a word bold or italic?
In most major IDEs, such as IntelliJ's IDEA, Apache Netbeans or Eclipse; you can type
/**
and press enter and it will generate the Javadoc for your method, including parameters, return values, etc. You just need to put in the descriptions.
The same applies for class declarations (the Javadoc comment always relates to the following element)
For instance
/**
* create_instance
* #param array of attributes for instance containing web, db, arrival_rate, response_time for instance
* respectively.
* #return Instance object
*/
How do you explain what the Params Stands for?
Use #param tag:
/**
* #param paramName Explanation of the param
*/
public void foo(String paramName);
How do you create a new line, or make a word bold or italic?
Use standard HTML, i.e. <p></p>, <br/>, <strong> and <em> (or less semantic <b> and <i>)
I'm not too experienced with Java yet, and I'm hoping someone can steer me in the right direction because right now I feel like I'm just beating my head against a wall...
The first class is called MeasuredParams, and it's got 40+ numeric fields (height, weight, waistSize, wristSize - some int, but mostly double). The second class is a statistical classifier called Classifier. It's been trained on a subset of the MeasuredParams fields. The names of the fields that the Classifier has been trained on is stored, in order, in an array called reqdFields.
What I need to do is load a new array, toClassify, with the values stored in the fields from MeasuredParams that match the field list (including order) found in reqdFields. I can make any changes necessary to the MeasuredParams class, but I'm stuck with Classifier as it is.
My brute-force approach was to get rid of the fields in MeasuredParams and use an arrayList instead, and store the field names in an Enum object to act as an index pointer. Then loop through the reqdFields list, one element at a time, and find the matching name in the Enum object to find the correct position in the arrayList. Load the value stored at that positon into toClassify, and then continue on to the next element in reqdFields.
I'm not sure how exactly I would search through the Enum object - it would be a lot easier if the field names were stored in a second arrayList. But then the index positions between the two would have to stay matched, and I'm back to using an Enum. I think. I've been running around in circles all afternoon, and I keep thinking there must be an easier way of doing it. I'm just stuck right now and can't see past what I've started.
Any help would be GREATLY appreciated. Thanks so much!
Michael
You're probably better off using a Map rather than a List, you can use the enum as the key and get the values out.
Map<YourEnumType,ValueType> map = new HashMap<YourEnumType,ValueType>();
#Tom's recommendation to use Map is the preferred approach. Here's a trivial example that constructs such a Map for use by a static lookup() method.
private enum Season {
WINTER, SPRING, SUMMER, FALL;
private static Map<String, Season> map = new HashMap<String, Season>();
static {
for (Season s : Season.values()) {
map.put(s.name(), s);
}
}
public static Season lookup(String name) {
return map.get(name);
}
}
Note that every enum type has two implicitly declared static methods:
public static E[] values();
public static E valueOf(String name);
The values() method returns an array that is handy for constructing the Map. Alternatively, the array may be searched directly. The methods are implicit; they will appear in the javadoc of your enum when it is generated.
Addendum: As suggested by #Bert F, an EnumMap may be advantageous. See Effective Java Second Edition, Item 33: Use EnumMap instead of ordinal indexing, for a compelling example of using EnumMap to associate enums.