Cant get public boolean removeBorrower(String libraryNumber) to work - java

The code needs to be able to reference two library numbers together, and if they are equal, remove the borrower from the array.
It won't let me run a method from another class because it's a static context. I don't know how else to solve this.
Here is what I have so far:
public boolean removeBorrower(String libraryNumber)
{
if(libraryNumber == null)
return false;
else if(Borrower.getLibraryNumber().equals(libraryNumber)))
borrowers.remove(Borrower);
return true;
}

You need to pass a reference to the other Borrower you want to compare against:
public boolean removeBorrower(String libraryNumber, Borrower otherBorrower)
{
if(libraryNumber == null)
return false;
else if(otherBorrower.getLibraryNumber().equals(libraryNumber)))
borrowers.remove(otherBorrower);
return true;
}
Before, you were trying the get the library number for the generic Borrower class, which doesn't make conceptual sense. With this code, you have a specific person to check the library number of.

You need to get an instance of the class containing removeBorrower method.
I don't think that you can't run the method from another class (unless the method is contained in a package-private class and the client class is not part of the same package).
Maybe you wanted to say that you're not allowed to run this method without having a reference to an existing instance of the class containing removeBorrwer method.

Related

Is it necessary to have toString() in an enum in Java?

I don't think we can instantiate an Enum. So do we need to have toString(), equals() and hashCode() method for an enum? Is this statement true?
Also as a follow up question
What does "this" keyword refers to in the following enum class?
public enum DocuType {
text, print, html, pdf; //Why aren't these in caps?
public boolean isPrint() {return this == print; } //What does this refers to?
public boolean isText() {return this == text; }
public boolean isTextOrPrint() { return isText() || isPrint(); }
}
How do I call any of the boolean methods of this enum as they are not static?
Also when I call, what does the keyword "this" refers to ?
I don't think we can instantiate an Enum.
Enum is one of type as we have class type. The way we can create instance (i.e. create variable) of a class, similarly we can create variables of Enum but that's only during during its definition which eventually makes them a Constant.
So do we need to have toString(), equals() and hashCode() method for an enum?
equals() & hashcode() are used to compare two instances. In case of class instances, the instances are created dynamically. So this means we don't have knowledge about instances beforehand and hence we need to compare them to know if they are equal. However, in case of Enum we know the instances when we define the Enum. So, we know beforehand whether they are equal or not. If the enum instances mean to be equal why on the earth we need two separate equal enum instances. So, in case of enum we generally don't override these methods.
What does "this" keyword refers to in the following enum class?
&
How do I call any of the boolean methods of this enum as they are not static?
&
Also when I call, what does the keyword "this" refers to ?
this means an instance currently in access. In your example, you have DocuType instances as text, pdf, print, html. When you invoke a method on any of the instance, ex: DocuType.text.isPrint(), this keyword inside the isPrint method will point to text. So, for instance pdf, all the methods will return false except isPdf().
So do we need to have toString(), equals() and hashCode() method for an enum? Is this statement true?
You don't need any of these methods in the enum.
Also as a follow up question What does "this" keyword refers to in the following enum class?
Imagine you have this code:
DocuType myType = DocuType.print;
If you want to check if the document is a PRINT document, you can do this:
boolean isPrint = myType.isPrint();
In this case, this is the myType, which means that it's the print enum. In the end, the result is true, because print == print;
I would also suggest to read the Tutorial to Enums
It seems you lack the knowledge of the concept of an enum.
And to your last question, an enum is static, but each "type" of it is an object, meaning you can do
DocuType.html.isText(); // false
DocuType.print.isPrint(); // true
To initalize your own Enum you have to
DocuType TextDocu = DocuType.text;
And you can write them in CAPS, but you don't have to, but it's recommened.
To explain it more in detail:
enum DocuType //this is an enum and not instantiatable
text,print,html,pdf // these are Objects with the functions of the enum and are an instance
As preparation for an explanation, a quick glance back in history.
Before enums were available in Java, a possible replacement could have been constructed like that:
public class DocuType {
public final static DocuType text=new DocuType();
public final static DocuType print=new DocuType();
public final static DocuType html=new DocuType();
public final static DocuType pdf=new DocuType();
private DocuType(){}; // hide constructor
public boolean isPrint() {return this == print; }
public boolean isText() {return this == text; }
public boolean isTextOrPrint() { return isText() || isPrint(); }
}
As you can see, while you cannot create new instances of DocuType, 4 static instances of them are already prepared for you in the Class.
Javas enum work very similar to that example (less writing involved, obviously); therefore, this refers to the instance you execute the method on. Regarding toString, it's up to you; the default implementation can be good enough or not. There is no need to implement neither equals nor hashCode.

comparing object calling the method

i know this is very trivial, but for some reason i'm having a little trouble. i'm trying to write a method that has a book object from an array list calling the method that compares it to another book in the same list. I think i got the gist of it but i'm just not understanding how to compare them. i think it's supposed to look something like this.
public Boolean isShorter(Book otherBook)
{
if(otherBook.getLength() < ???????.getLength() )
return true;
else
return false;
}
use "this" keyword to refer to the current object (the caller of the method).
like this:
otherBook.getLength() < this.getLength()

Passing and setting booleans - Java/Android

I have a class like so:
public class Achievements(){
boolean score100_Earned_Offline;
boolean score1000_Earned_Offline;
final String score100 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
final String score1000 = "xxxxxxxxxx" //where xxxxxxxxxx would be replaced with the achievement's Google Play Games ID
}
In my Game class, I check the state of the achievements every tick and act on them as necessary like so (assume all methods to be valid and defined - this is cut down to provide the code necessary to the question).......
public class Game(){
public void checkAchievements(Achievements achievements){
if (score>=100){
unlockAchievement(achievements.score100, achievements.score100_Earned_Offline);
}
if (score>1000){
unlockAchievement(achievements.score100, achievements.score1000_Earned_Offline);
}
}
public void unlockAchievement(String achievementToUnlock, boolean thisAchievementOfflineFlag){
//If user is signed in, then we are ready to go, so go ahead and unlock the relevant achievement....
if (checkSignedIn()){
Games.Achievements.unlock(getApiClient(), achievementToUnlock);
//Otherwise, I want to do is set the relevant flag to true so it can be checked when the user does eventually log in
else{
thisAchievementOfflineFlag=true;
}
}
}
Pass by value
In the 'unlockAchievement' method, the boolean 'thisAchievementOfflineFlag' does get set to true if the user is not logged in, however, it doesn't effect the actual boolean that was originally sent into the method (which as you can see is defined in my 'Achievements' class). I'm guessing this is because Java is Pass by Value and is therefore, creating a local copy of the variable which is valid inside the method only. I did try using Boolean too (wrapper class) but got the same results.
Other ways to achieve this?
I've currently got it set up so I can define each achievement as an enum so each one will have it's own copy of the boolean flag. However, I'm aware that it's not recommended to use enums in Android so if there is a better way that I am missing, I would rather avoid them.
Please note that I don't want to use if checks or switch statements as this is taking place in a game-loop.
Any suggestions appreciated
This is all because Java's implementation of Boolean (also, for example String) is immutable for safety reasons. You can see it here: http://www.explain-java.com/is-string-mutable-in-java-why-wrapper-classes-immutable-in-java/
You can solve your problem by introducing an object wrapper for that boolean:
public class BooleanWrapper {
private boolean value;
public void set(boolean value) {
this.value = value;
}
public boolean get() {
return value;
}
}
Now, this object reference will be passed by value but will still point to the same BooleanWrapper object on the heap. You can simply use getters and setters to change the inner boolean value.
Then your code would become:
public void unlockAchievement(String achievementToUnlock, BooleanWrapper thisAchievementOfflineFlag){
if (checkSignedIn()){
Games.Achievements.unlock(getApiClient(), achievementToUnlock);
else {
thisAchievementOfflineFlag.set(true);
}
}
Java is pass-by-value:
When you pass boolean then you for sure passed it by value, while it is a primitive type. When you pass Boolean, you would think it's an object and that you can change it's state, but actually you cannot because Boolean is implemented as an immutable object (as already said). You can confirm this just by reading the code of java.lang.Boolean.
But if you create your own wrapper class, and in a sense, you control whether you implement it in immutable or mutable way. BooleanWrapper I wrote lets you change the state of that object. And when you pass an object such as this one to the method, it's passed by value. That means that another reference is created, but it points to the same object on heap (see image below).
You could use an AtomicBoolean, which will have pass-by-reference semantics.

Issue with instance variables

My overall goal at the moment is to call a method that is in a different class, there is no inheritance between the classes.
After researching i found the best way to do this was to initialise an instance of the object in the method I am trying to call it in.
Is there a standard way to do this?
Any help will be greatly appreciated.
You have to pass the correct parameter values, not declare them again. Like this:
Book b = new Book(title, author, publisher, year);
Of course, you have to know the values for title, author, publisher, year before calling the constructor. Also, the method is expecting a boolean return value, so you must have a return true; or return false; at the end, depending on what the method is expected to do.
i get the error "Constructor Book in class Book cannot be applied to
given types
Because you did'nt specified a no-args constructor in your Book class
I assume that you want to check if the book already exists
won't compile since this method (i.e the method checkForDuplicate()) doesn't return a boolean in all the cases (when b.equals() is false).
So you should do
if(b.equals() == true){
return true;
}else {
return false;
}
which is equivalent to return b.equals();

java - the use of 'this' within the brackets of a method

System.out.println(this);
Why would you use 'this' in the brackets? Is it for printing the references? Or as in the code below for comparing if the object points to the same reference?
public void compareDrzewo(Drzewo tree)
{ if (tree == this)
{ System.out.println("true"); }
else { System.out.println("false"); }
main method code
Drzewo name1 = name2;
name1.compareDrzewo(name2);
The other examples of the use of 'this.' are quite straight forward (inner class etc.) Please comment only on this or similar use.
That instance has a toString() method associated with it, which means it will invoke it to print out meaningful information, or it uses Object's toString() (meaning it'll print out a memory location, which is much less useful).
System.out.println(this)
is the same as
System.out.println(this.toString());
So if the class of which this is an instance overrides the toString method, that line of code would be meaningful.
You use this to refer to the current object.
One example is when your want to refer to the current instance of your class, so if you need to call a method with your class, for example something.equals(this) or something == this.
Another example is explicitly specifiying a class instance of a variable rather than a local instance, for example a setter:
public void setMyVar(String myVar) {
this.myVar = myVar;
}
So myVar is the variable declared in the method, this.myVar is the variable declared in your class.

Categories