I am newbie in Java. How to create function to get one object or null?
I have simple class:
public class Auto {
Auto (String text) {
}
}
And other class I would like to have method onAuto:
public class AutoSearch {
public Auto oneAuto()
{
//operations
String text = getOperations();
if (text) {
Auto auto = new Auto(text);
return auto;
} else {
return null;
}
}
}
But this not working, because method have to return object Auto.
What if I can't create object Auto in this method? How can I do it?
You want to verify if text exists in order to create an Auto object, am I correct?
public class AutoSearch {
public Auto oneAuto() {
String text = getOperations();
if (text != null) {
return new Auto(text);
} else {
return null;
}
}
}
You can do this in a more compact way too, using the ternary operator:
public class AutoSearch {
public Auto oneAuto() {
return text != null ? new Auto(text) : null;
}
}
Yet, in Java the expression inside an if statement MUST resolve to an boolean (true or false). You seems to think that Java works like Javascript, and its definitely not the case. Java and Javascript have only the name in common.
As davidxxx said, probably you will need to define the Auto constructor as public.
1) if (text) is not a boolean expression.
It cannot compile. But if (text != null) can.
2)You declared the Auto constructor with a package private access modifier.
It means that AutoSearch has to be in the same package as Auto to be able to invoke this constructor.
Or else change the Auto constructor to public :
public Auto (String text) {
....
}
You need to check if the text is empty or not. if it is empty return null and if it have content, then return the Object
if("".equals(text) || text == null){
return null;
} else {
return auto
}
Related
I wanted to know if is it possible to have a method that can choose between multiple classes and return one of them.
This is what it should look like:
public class BotManager {
public static Test test;
public static int PROTOCOL_VERSION = 114;
public Bot bot(){
if(PROTOCOL_VERSION == 114){
return test.bot114;
}else{
return test.bot111;
}
}
in this example, bot111 and bot114 are different classes.
bot.version111.bot.Bot;
bot.version114.bot.Bot;
Yeah of course you can.
You just need to be sure that bot114 and bot111 both extend the Bot class.
For these purposes you would use what's called a factory, here is an example of a factory that returns different Windows based on the Class type:
public static Window getCsvExportWindow(Class tab) {
if (tab == OnhandTab.class) {
return new OnhandCsvExportWindow();
} else {
return new CustOrderCsvExportWindow();
}
}
Instead of Class type you use your PROTOCOL_VERSION.
You can use it's code:
if (Object object instanceof Bot114) {
return new Bot114();
} else if (Object object instanceof Bot111) {
return new Bot111();
} else {
return null;
}
hi I'm rewriting a java code in C# and I'm stuck here:
public void printSolveInstructions() {
System.out.print(getSolveInstructionsString());
}
public String getSolveInstructionsString() {
if (isSolved()) {
return historyToString(solveInstructions);
} else {
return "No solve instructions - Puzzle is not possible to solve.";
}
}
public List<LogItem> getSolveInstructions() {
if (isSolved()) {
return Collections.unmodifiableList(solveInstructions);
} else {
return Collections.emptyList();
}
}
I know how to rewrite the first two methods (it's for referencing the last one) but I don't know the equivalent for Collections.unmodifiableList() and Collections.emptyList()
solveInstructions is of type List here's the declaration in java and C#:
private ArrayList<LogItem> solveInstructions = new ArrayList<LogItem>() // java
private List<LogItem> solveInstructions = new List<LogItem>() // c#
update
I rewrote the getSolveInstructions() method in this way:
public List<LogItem> getSolveInstructions()
{
if (isSolved())
{
return solveInstructions.AsReadOnly();
}
else
{
return new List<LogItem>();
}
}
Now the problem is ide gives me an error when I use .AsReadOnly()
Your method returns either a List<LogItem>, or an IReadOnlyCollection<LogItem> (produced by call to List<T>.AsReadOnly() method; however, your return type is List<LogItem>, which is incompatible with the IReadOnlyCollection<LogItem>. Change your method return type to IList<LogItem>, which works for both types.
Note, since this method can return either a read-only or a read-write list, calling code should check the returned collection's IsReadOnly property, before attempting to modify it.
I have an enum with values VALID and INVALID, which have a boolean property associated with them. I would like to get the enum value based on a boolean value I provide.
If it is true I should get VALID, if it is false I should get INVALID. I would like to do so in a getter method like the below, based on the value of the member variable
public boolean getCardValidityStatus() {
return CardValidationStatus status = CardValidationStatus(this.mCardValidityStatus));
}
My code:
private enum CardValidationStatus {
VALID(true),
INVALID(false);
private boolean isValid;
CardValidationStatus(boolean isValid) {
this.isValid = isValid;
}
public boolean getValidityStatus() {
return this.isValid;
}
}
You're able to achieve that using a static lookup method in the enum itself:
private enum CardValidationStatus {
VALID(true),
INVALID(false);
//...
public static CardValidationStatus forBoolean(boolean status) {
//this is simplistic given that it's a boolean-based lookup
//but it can get complex, such as using a loop...
return status ? VALID : INVALID;
}
}
And the appropriate status can be retrieved using:
public CardValidationStatus getCardValidityStatus() {
return CardValidationStatus.forBoolean(this.mCardValidityStatus));
}
I would add a parse method to your enum, which takes the boolean, iterates over all the values and returns the one that matches, for example:
public CardValidationStatus parse(boolean isValid) {
for (CardValidationStatus cardValidationStatus : CardValidationStatus.values()) {
if (cardValidationStatus.getValidityStatus() == isValid) {
return cardValidationStatus;
}
}
throw new IllegalArgumentException();
}
#ernest_k solution made this work, but I think that's not reliable solution.
You should always do code which is independent.
Because his solution is hardcoded. What if values of VALID & INVALID are changed. Will you change your forBoolean logics also?
Because he did not check what the Enum fields are holding inside it.
Reliable solution will be #DaveyDaveDave answer. This will also work when you have many status with VALID & INVAlID.
private enum CardValidationStatus {
VALID(true),
INVALID(false);
//...
public CardValidationStatus forBoolean(boolean isValid) {
for (CardValidationStatus cardValidationStatus : CardValidationStatus.values()) {
if (cardValidationStatus.getValidityStatus() == isValid) {
return cardValidationStatus;
}
}
throw new IllegalArgumentException();
}
}
Suggestion (Easiest way I think)
Why are you making Enum just for storing 2 boolean values?
Just make static boolean named by VALID & INVALID.
public static final boolean CARD_STATUS_VALID = true;
public static final boolean CARD_STATUS_INVALID = false;
if(cardStatus == CARD_STATUS_VALID){
// todo
}
I am trying to abstract some common checks for an Android library and add Nullability annotations at the same time but I am getting a warning.
Let's say I have an example method in this library:
public int method(#Nullable final String param) {
final int precheckResult = LibPrechecks.checkForMethod(param); // Does check for param not being null
if (LibPrechecks.checksFailed(precheckResult)) {
return precheckResult;
}
// Rest of logic
return internalMethod(param); // IDE is complaining that param cannot be null
}
That then calls another internal method of the library for some processing:
private int internalMethod(#NonNull String param) {
// processing logic
return 0;
}
And here is an example "precheck" class:
public class LibPrechecks {
public static int checkForMethod(#Nullable final String param) {
if (param == null) {
return -1;
}
return 0;
}
public static boolean checksFailed(final int precheckResult) {
return precheckResult < 0;
}
}
I am returning an error code upon a null so I know it's safe and non-null by the time the internal method is called with the param, but the IDE is still unhappy and thinks the param could be null. How would I fix the warning in Android Studio and do this properly?
The IDE doesn’t know what checkForMethod() or checksFailed() do, so you need to either suppress the warning or write some code that the IDE can statically analyze to prove that param is not null.
I think the best thing to do would be to assert that param is not null after the precheck code is done running. Either
assert param != null;
or
if (param == null) throw new AssertionError();
will work.
This is the code of the method that I want to simplify. The method name I call of SerializedExpFamMixture class is exactly the value of "model", my question is how to assign the value of "model" directly as the name of the method instead of using "if" to determine which method I should call. Since by using "if", I need to list all the possible values of "model" and judge which method I should use.
Thank you very much for help. I am new to java.
public static SerializedExpFamMixture RateMtxModel(String model)
{
SerializedExpFamMixture result=new SerializedExpFamMixture();
if(model=="kimura1980()")
result=SerializedExpFamMixture.kimura1980();
if(model=="accordance()")
result=SerializedExpFamMixture.accordance();
if(model=="pair()")
result=SerializedExpFamMixture.pair();
return result;
}
One way you can approach this is to use Reflection:
Method method = myClass.getClass().getMethod("doSomething", null);
method.invoke(myClass, null);
Since you are new to Java, it's time for some general pointers:
In Java, we usually name our methods with camelCase, so the first letter is lower case.
Also, in Java we usually leave the opening curly-bracket on the same line as the code (no newline).
Always use final on your variables. At least your parameters. That way you won't overwrite it, and thus won't have to try to figure out which value it actually has at runtime.
Use curly-brackets! Please!
The result variable is not actually needed.
Use the equals-method to compare Strings.
If you only want one result, use else-if
Fixing these things, your method looks like this:
public static SerializedExpFamMixture rateMtxModel(String model) {
if (model.equals("kimura1980()")) {
return SerializedExpFamMixture.kimura1980();
} else if (model.equals("accordance()")) {
return SerializedExpFamMixture.accordance();
} else if(model.equals("pair()")) {
return SerializedExpFamMixture.pair();
}
return new SerializedExpFamMixture();
}
Next, let's look at what you are actually trying to do here. You want to pass some Strings around, and use them as a basis for creating objects. And now, with the advice given here, you will do this using reflection. This does not sound like a very good idea to me. Say you were to go through with this, and this happened:
rateMtxModel("kinura1980");
Small typo, hard to spot, will give unexpected results. If you were actually calling a method the compiler would let you know that you messed up, now you will get no warning (btw did you see both errors in that method call?). The same if someone were to delete the accordance()-method, the compiler would not alert them that this will break the program.
If it was up to be I would just use the static factory-methods in SerializedExpFamMixture directly, but if you have to do it like this (if the task at hand is using a String input to create an object) I would do something like this:
public enum Something {
KIMURA1980("kimura1980()"),
ACCORDANCE("accordance()"),
PAIR("pair()");
private final String stringValue;
private Something(final String stringValue) {
this.stringValue = stringValue;
}
public static Something fromString(final String string) {
for (final Something something : values()) {
if (something.stringValue.equals(string)) {
return something;
}
}
return null;
}
}
public static SerializedExpFamMixture rateMtxModel(final String model) {
if (model == null) {
throw new IllegalArgumentException("model is null!");
}
final Something something = Something.fromString(model);
if (something == null) {
return new SerializedExpFamMixture();
}
switch(something) {
case KIMURA1980:
return SerializedExpFamMixture.kimura1980();
case ACCORDANCE:
return SerializedExpFamMixture.accordance();
case PAIR:
return SerializedExpFamMixture.pair();
default:
return new SerializedExpFamMixture();
}
}
This way, the one place where you will use the Strings is in the enum, the rest of the code will use the enum constants and thus have the safety of the compiler to rely on.
One could also leave the linking between operation and String to the enum, like this:
interface Operation<T> {
public T run();
}
public enum Something {
KIMURA1980("kimura1980()", new Operation<SerializedExpFamMixture>() {
public SerializedExpFamMixture run() {
return SerializedExpFamMixture.kimura1980();
}
}) ,
ACCORDANCE("accordance()", new Operation<SerializedExpFamMixture>() {
public SerializedExpFamMixture run() {
return SerializedExpFamMixture.accordance();
}
}),
PAIR("pair()", new Operation<SerializedExpFamMixture>() {
public SerializedExpFamMixture run() {
return SerializedExpFamMixture.pair();
}
}),
DEFAULT(null, new Operation<SerializedExpFamMixture>() {
public SerializedExpFamMixture run() {
return new SerializedExpFamMixture();
}
});
private final String stringValue;
private final Operation<SerializedExpFamMixture> operation;
private Something(final String stringValue, final Operation<SerializedExpFamMixture> operation) {
this.stringValue = stringValue;
this.operation = operation;
}
public static Something fromString(final String string) {
if (string != null) {
for (final Something something : values()) {
if (string.equals(something.stringValue)) {
return something;
}
}
}
return DEFAULT;
}
public SerializedExpFamMixture getCorrespondingSerializedExpFamMixture() {
return operation.run();
}
}
With this setup in the enum (I think the Operation-part can be trimmed out with Java8), the method will be as simple as:
public static SerializedExpFamMixture rateMtxModel(String model) {
return Something.fromString(model).getCorrespondingSerializedExpFamMixture();
}
Use reflection, but you need to consider a few things:
Bug alert! Comparing Strings using == doesn't work as expected in java - use .equals() instead. However, the solution below bypasses that problem
For the general case, which includes methods not visible to the invoker, you need to consider accessibility, both in finding the method and invoking it
You don't need the result variable, and even if using your code, don't need to initialize it
Try this:
String methodName = model.replace("(", "").replace(")", "");
try {
// getMethod() returns only public methods, getDeclaredMethod() returns any visibility
Method method = SerializedExpFamMixture.class.getDeclaredMethod(methodName);
// if the method is not guaranteed to be visible (eg public) you need this:
method.setAccessible(true);
return (SerializedExpFamMixture) method.invoke(null); // how to invoke on the class object
} catch (Exception forBrevity) {
return new SerializedExpFamMixture();
}