Limiting a function's input to specific integers [duplicate] - java

This question already has answers here:
Java Class Constructor Parameters with range limits
(3 answers)
Closed 5 years ago.
What is the best practice to limit a functions inputs to specific integers in java?
lets say
public Car(CarColor carcolor, (Range limited integer value) carnum) {
// Rest of the code
}
For strings the best way is to use enumeration like
enum CarColor{
Blue, Black, Red, Green
}
But it wont work for integers
enum CarNumber{
1,2,3,4,5
}
What i came up with is this:
enum CarNumber{
c1, c2, c3, c4, c5;
#Override
public String toString() {
return this.name().substring(1);
}
}
But I'm pretty sure this is not a good practice.
I also don't want to let the function be called by any integer and check with a if inside the function like below. The function should not be able to be called and limited with a enum like style.
public Car(CarColor carcolor, int carnum) {
if (carnum < 0 || carnum > 5)
return ;
// Rest of the code
}

Maybe your best bet is to make a class that only takes in a variable that is between a certain range and then only accept an instance of that class as a parameter in your function. This way, your function won't have to check anything because it already knows that it won't be outside of a range.

Related

How to unreverse this method in java?

I wrote some code:
public class digitShow {
public static void main(String[] args) {
System.out.println(digitShow(98198187));
}
public static int digitShow(int num) {
if (num != 0) {
System.out.print(num % 10);
return digitShow(num / 10);
} else
return num;
}
}
The code works perfectly fine, but I am trying to make it so instead of printing the numbers in reverse order one by one, the output rather would display each digit one by one in the order that they are entered in the parameter.
So in this case:
1
2
3
4
I've been trying to un-reverse it, but I've had no luck.
Ok, some people on comments are suggesting using arrays or similar. This is correct, however this seems like a question made by someone who is learning recursion (and, as a teacher, I can smell a homework question here).
I will not post the answer because I'd be doing your homework for you and we need good programmers in this world. If I (or anyone else) do your homework you'll never understand the basic concepts of programming, and never becoming a good programmer.
Now, building on top of smac89's comment:
Your code to reverse has an issue: it prints 0 after it reverses the digits. Why? because you are returning an integer and then printing it in your main function but you are not really using the return value anywhere else.
Try calling your method without the System.out.println in main and see what happens.
So, basically, evaluate if you really need to return an integer and, if you don't, you can now evaluate how you are calling the recursion (again, read smac89's comment).
I wish you the best in your studies!
You need to reduce the number by successive divisions first. Then process the values as they are unwound from the stack. This will print the most significant to least significant digit. Then return the starting number.
public static int digitShow(int num) {
if (num > 10) {
digitShow(num/10);
}
System.out.println(num%10);
return num; // returns the starting number.
}
prints
9
8
1
9
8
1
8
7
98198187

Is it valid to add a Null check and access the Integer value in the same line of if condition in Java [duplicate]

This question already has answers here:
Java logical operator short-circuiting
(10 answers)
Java null check on object
(5 answers)
Closed 2 years ago.
Say
class Person{
Integer height;
integer weight;
}
is it valid to check like this?
Person p = new Person();
if (p.height !=null && p.height >= 1 && p.weight >=1 ){}
It's fine, but note that this will still crash with a NullPointerException if p.weight is null. If you want clean code, consider this question:
What does height is null actually mean? Does it mean:
It is semantically equivalent to 0. (Then, why have it? Make your fields int, and set them properly).
It is unknown.
It is unset; this is a person who does not want their height publicized.
In particular, given that you are checking for >= 1, apparently you can have a null height, but also a negative height. What is the semantic difference between these two? If there is no difference, why are you allowing a cavalcade of different internal values that nevertheless all boil down to representing the same state? You're signing up for a bevy of checks everytime you interact with these variables, and a combinatorial explosion to test all this. Don't do it this way - create a single value to represent 'invalid' or 'unknown' or 'intentionally omitted' or whatever it is that you need to convey.
Usually it leads to better code if you [A] eliminate invalid state as early as possible, which in particular means that you do not need to check for invalid state (here, 0 and negative numbers appear to be intended as invalid) every time you use these variables, and [B] use a sentinel value and not null to indicate a unique state such as 'unset' or 'intentionally not shared'.
In other words:
Make height and weight private
Their setters will refuse to set (and throw IllegalArgumentException instead) if trying to set 0 or negative height or weight.
The fields are of type int
Constants exist for the various alternate states.
public class Person {
private static final int UNKNOWN = -1;
private static final int INTENTIONALLY_OMITTED = -2;
private int height, weight;
public Person() {
this.height = UNKNOWN;
this.weight = UNKNOWN;
}
public void setHeight(int height) {
if (height < 1) throw new IllegalArgumentException("Non-positive height");
this.height = height;
}
public void setHeightOmitted() {
this.height = INTENTIONALLY_OMITTED;
}
}
and so on. Now you can write code that is inherently readable; null is nebulous (you'd have to document what it means. Does it mean unset, or invalid, or intentionally omitted? What?), if (height == INTENTIONALLY_OMITTED) documents itself, that's a good thing.
Yes this is valid because Integer is the class representing int.
This is the reason why Integer can hold a null value. Comparison at p.height and p.weight is also valid.
Yes, because in case of && operation if first condition is true, then after second condition will be checked. If p.height is null then, First condition is false so, no other conditions will be checked.
You also have to add null check for p.width also.

Issue converting double to boolean

I am working on a project in my Java class that is using multiple classes as well as GUI (not sure if that info is relevant). My group partner and I have come across an issue though. We have a Validator class, that should validate a "SSN" but we are continuously given the error:
java:146: error: incompatible types: double cannot be converted to boolean
if(Validator.isValidSSN(jTextFieldEmpSSN)){
Now obviously java:146 is the line. the code we have for each class is:
employeeUI class (the one showing the error):
private void jButtonEnterActionPerformed(java.awt.event.ActionEvent evt)
{
Employee e=new Employee();
if(Validator.isValidName(jTextFieldEmpFirst)){
if(Validator.isValidName(jTextFieldEmpLast)){
if(Validator.isValidEmail(jTextFieldEmpEmail)){
if(Validator.isValidSSN(jTextFieldEmpSSN)){
e.setFirstName(jTextFieldEmpFirst.getText());
e.setLastName(jTextFieldEmpLast.getText());
e.setEmailAdd(jTextFieldEmpEmail.getText());
e.setSSN(Integer.parseInt(jTextFieldEmpSSN.getText()));
}}}}
and the Validator class for isValidSSN is:
public static double isValidSSN(JTextField textfield)
{
double number = 0;
boolean inRange = false;
while(!inRange)
{
number = Double.parseDouble(textfield.getText());
if (number >= 100000000 && number <= 999999999)
{
inRange = true;
} else {}
}
return number;
}
We have been beating our head on how to fix this for quite some time, but are coming up at a loss. Are we missing something? we would greatly appreciate any help with this.
If I ask, "Is 123-45-6789" a valid SSN?" you wouldn't reply "123456789.0", would you? You'd give me a yes or a no. By returning double your method is doing the former. It's responding with a number instead of an answer to the question.
A good rule of thumb is that methods starting with is or has should return booleans. "Is this a valid SSN?" is a yes/no question, so isValidSSN should return the programming equivalent of yes/no.
public static boolean isValidSSN(JTextField textfield)
There are a couple of other design points here:
The loop isn't necessary. The SSN is either valid or it isn't.
A text field is not itself an SSN. It holds some text, and that text is the SSN. Rather than taking a text field and looking up the text in the field with getText(), it'd be better to have isValidSSN take the text directly. Let the caller extract the text from the text field.
In broader terms this is known as the single responsibility principle. Every method should ideally do just one thing.
Result:
public static boolean isValidSSN(String ssn) {
double number = Double.parseDouble(ssn);
if (number >= 100000000 && number <= 999999999) {
return true;
}
else {
return false;
}
}
P.S. If I don't mention it someone will surely comment that the if and else blocks aren't necessary; one can return the if result directly. They would be right, though I consider it a bit of an advanced trick. It would look like so:
public static boolean isValidSSN(String ssn) {
double number = Double.parseDouble(ssn);
return number >= 100000000 && number <= 999999999;
}

Converting a binary string to integer using a basic mathematical operator

Main:
public class Main{
public static void main(String[] args){
System.out.println(Convert.BtoI("10001"));
System.out.println(Convert.BtoI("101010101"));
}
}
Class:
public class Convert{
public static int BtoI(String num){
Integer i= Integer.parseInt(num,2);
return i;
}
}
So I was working on converters, I was struggling as I am new to java and my friend suggested using integer method, which works. However, which method would be most efficient to convert using the basic operators (e.g. logical, arithmetic etc.)
.... my friend suggested using integer method, which works.
Correct:
it works, and
it is the best way.
However, which method would be most efficient to convert using the basic operators (e.g. logical, arithmetic etc.)
If you are new to Java, you should not be obsessing over the efficiency of your code. You don't have the intuition.
You probably shouldn't optimize this it even if you are experienced. In most cases, small scale efficiencies are irrelevant, and you are better off using a profiler to validate your intuition about what is important before you start to optimize.
Even if this is a performance hotspot in your application, the Integer.parseint code has (no doubt) already been well optimized. There is little chance that you could do significantly better using "primitive" operations. (Under the hood, the methods will most likely already be doing the same thing as you would be doing.)
If you are just asking this because you are curious, take a look at the source code for the Integer class.
If you want to use basic arithmetic to convert binary numbers to integers then you can replace the BtoI() method within the class Convert with the following code.
public static int BtoI(String num){
int number = 0; // declare the number to store the result
int power = 0; // declare power variable
// loop from end to start of the binary number
for(int i = num.length()-1; i >= 0; i--)
{
// check if the number encountered is 1
/// if yes then do 2^Power and add to the result
if(num.charAt(i) == '1')
number += Math.pow(2, power);
// increment the power to use in next iteration
power++;
}
// return the number
return number;
}
Normal calculation is performed in above code to get the result. e.g.
101 => 1*2^2 + 0 + 1*2^0 = 5

Java get a random value from 3 different enums

I am implementing a simple version of the Cluedo game.
There are 3 types of cards in the game, Character, Weapon and Room. Since one card is nothing more than a String (i.e no functionality or information other than the name is stored in a card), I chose not to have a Card interface and each type extends Card. Rather I had three enums in my game which are:
public enum Character {Scarlett, Mustard, White, Green, Peacock, Plum;}
public enum Weapon {Candlestick, Dagger, LeadPipe, Revolver, Rope, Spanner;}
public enum Room {Kitchen, Ballroom, Conservatory, BilliardRoom, Library, Study, Hall;}
However there is one case where three types of cards are put together and dealt evenly to each player of the game. For example, one player may have a hand of 2 Characters, 2 Weapons and 1 Room, another player may have 3 Rooms and 2 Characters, so long the total number of cards are even it doesn't matter what type that is.
And that's why I wonder if there is a way to randomly choose one single value from all three enums in Java?
Or I shouldn't do this three enums thing in the first place? (Badly designed)
A simple way is to collect all the enum members into a single Object[], then take a random element from it.
Note that an enum can also implement an interface, so you can even have some shared API across all the enums. Typically you'll find yourself writing a lot of switch statements on the value of the enum; those can mostly be replaced by dynamic dispatch against such interface methods. Further note that each enum member can provide its own method implementation.
I think you should keep it like it is, but then put them all in the same list:
List<Enum> enums = new ArrayList<>();
enums.addAll(Arrays.asList(Character.values()));
enums.addAll(Arrays.asList(Weapon.values()));
enums.addAll(Arrays.asList(Room.values()));
And then you take random values of that list. More closely resembles what you do in real life.
You can write something like this:
public enum Character {Scarlett, Mustard, White, Green, Peacock, Plum;}
public enum Weapon {Candlestick, Dagger, LeadPipe, Revolver, Rope, Spanner;}
public enum Room {Kitchen, Ballroom, Conservatory, BilliardRoom, Library, Study, Hall;}
private static final Random RANDOM = new Random(); // random number generator - declared static, because we need only one for whole program
private static final int TOTAL_CARDS = Character.values().length + Weapon.values().length + Room.values().length; // sum up all enum lenghts - in this case, it will be 6 + 6 + 7 = 19
private Enum<?> getRandomCard() {
int randomNumber = RANDOM.nextInt(TOTAL_CARDS); // we "roll a dice" to get some random number. Let's assume that we get "15"
if (randomNumber < Character.values().length) { // is 15 less then 6? No, so we skip this part
return Character.values()[randomNumber];
}
randomNumber -= Character.values().length; // randomNumber = 15 - 6 = 9
if (randomNumber < Weapon.values().length) { // is 9 < 6 ? No, so we skip this
return Weapon.values()[randomNumber];
}
randomNumber -= Weapon.values().length; // randomNumber = 9 - 6 = 3
if (randomNumber < Room.values().length) { // Is 3 < 7 ? Yes!
// so it means that our "dice" has chosen a Room with array index 3
// We call Room.values() to get all room types as an array and then we pick one with index 3
return Room.values()[randomNumber];
}
return null; // should never happen
}
If you don't understand any part of this, please let me know - I'll add some comments.
However, I believe that solution proposed by Oskar Kjellin is far more elegant then this one :)

Categories

Resources