Where to put methods scanner concretely(Java) - java

so my question is very short, I have a java constructor, and a java class that has to use the constructor to build an object.I need to ask the user for arguments that are required to build the object.Normally, do I put the required scanner(to make user input arguments) in the correct constructor methods or I ask these directly in the class methods thats use the constructor?For example, having construc.java(wich is the constructor)and contains methods like:¸
public void setNumber(int JNumber){
if(JNumber>=0){
Number = JNumber;
and a file called caller.java thats contain methods like:
public void add();
construc test = new construc(string,int,int,string,string); //instance to use the constructor methods
So basically im wondering where to put this code part that ask for the number to assign the the object:
Scanner thenum = new Scanner(System.in);
System.out.print("Entrez la quantité: \n");
int ob1num = thenum.nextInt();
ob1num = JNumber;
setNumber(JNumber);
I am a little bit confuse in Java(and beginner).Thank you!

This depends on how you want to use your setNumber() method. If you also want to use it to set numbers that are not based on the users input, putting the Scanner outside of the method is advised. Personally I would have the Scanner outside of the method to make which would make the method more versatile. If you need to scan multiple numbers, maybe put the scanning part in its own method that returns an int based on the users input.
class YourClass {
YourClass() {
//Initialize
setNumber();
}
}
public static main(String[] args) {
//Create new YourClass object and set value from user input
YourClass object = new YourClass();
}

With getter and setter methods available in the MyClass.Your main class methods can read values
Scanner thenum = new Scanner(System.in);
System.out.print("Entrez la quantité: \n");
int ob1num = thenum.nextInt();
And pass value to constructor
MyClass(int JNumber,String JString){
this.JNumber = JNumber;
this.JString = JString;
}

Related

Is there a faster/simpler way of constructing objects from scanned inputs

Imagine you want to create an unknown amount of instances of a class. You decide to use an ArrayList (if there is a better option I would very much appreciate if someone could explain this) You want to allow instances of the class to be created through the System Input.
import java.util.ArrayList;
import java.util.Scanner;
class MyClass {
static ArrayList<MyClass> myArrayList = new ArrayList<>();
int field1;
int field2;
int field3;
public MyClass(int field1, int field2, int field3) {
// contructor statements
}
Here is the problem, if you scan inputs, you cannot feed them into the constructor, as you need to print messages in between and then scan the input. You are forced to store the values of all the fields by assigning them to other variables as shown below, you can also set the fields at the index of the new object each time you scan them, but this seems like it would be slow and complicated code.
static void createNewInstance() {
Scanner myScanner = new Scanner(System.in);
System.out.println("Enter field 1");
int f1 = myScanner.nextInt();
System.out.println("Enter field 2");
int f2 = myScanner.nextInt();
System.out.println("Enter field 3");
int f3 = myScanner.nextInt();
myArrayList.add(new MyClass(f1, f2, f3));
}
}
So I am wondering if there is a way to pass the scanned input directly into the constructor, it seems like storing the values as variables would take a bit of computation and also, if these variables are primitive, i think they would be in stack, which stack has static memory allocation, so they are permanently there. It seems to me like on a large scale, this is not such a great solution, but I am also extremely limited in my knowledge of program performance, so I am not exactly sure. I am guessing the answer is just use that solution, any others are just too complicated to be worth using. Thank you for reading, sorry I have struggled to word this question in a concise way.
In "normal" situation you will never create objects like this - there are many many ways the application receiving objects (reading from batch, receiving HTTP requests, deserialization...) and I never saw "on production" prompting the user "now give me the value of the first field..." etc and scanning values
it seems like storing the values as variables would take a bit of computation
and that's not a problem at all - creating objects in Java is super fast, additional three primitive fields are not relevant at all when it comes to the performance
Don't overengineer this
Firstly, lets mention that Premature Optimization Is the Root of All Evil
Having mentioned that, if you still want to get your user input through the stdin, you could asks your user to provide his numbers at once.
e.g
"Provide your numbers seperated by ,"
And then, after using scanner.nextLine() you can split the line and get your numbers (and validate that all 3 numbers were given).
Builder pattern and optionally Project Lombok are your friends!
public static void main(String[] args) {
MyClass obj = createNewInstance();
}
public static MyClass createNewInstance() {
Scanner scan = new Scanner(System.in);
MyClass.MyClassBuilder builder = MyClass.builder();
builder.field1(scan.nextInt());
builder.field2(scan.nextInt());
builder.field3(scan.nextInt());
return builder.build();
}
#Builder
#RequiredArgsConstructor
public static class MyClass {
private final int field1;
private final int field2;
private final int field3;
}
Another option is to put Scanner directly to the constructor (but this is NOT GOOD from Object Design Principles)
public static void main(String[] args) {
MyClass obj = new MyClass(new Scanner(System.in));
}
public static class MyClass {
private final int field1;
private final int field2;
private final int field3;
public MyClass(Scanner scan) {
field1 = scan.nextInt();
field2 = scan.nextInt();
field3 = scan.nextInt();
}
}

call variable from another class

static int input;
Scanner scn = new Scanner(System.in);
public BusGenerator(Depot depot)
{
this.depot = depot;
}
public int getinput()
{
return input;
}
public void run()
{
System.out.println("Enter Number of Buses:" );
input = scn.nextInt();
}
I have a class called BusGenerator and from here i ask the user about the number of Bus and the system scans it and save it in the variable called "Input".
I have another class called Depot and i want to call the variable "Input" from the Class depot. Is there a way to do that?
As the code is, you can simply use BusGenerator.input in the Depot class to refer to it (as pointed out in the comments).
However, since you've already defined a getter for this variable, it might be more consistent to make input private and refer to it with the public getter/setter methods.

How do I know what type of variable to use for an instance of an object?

package RPG;
import java.util.Random;
import java.util.Scanner;
public class Beginnings
{
public static boid main (String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Pick a class:");
System.out.println("Fighter: Deals more damage");
System.out.println("Mage: Has more health");
System.out.println("Theif: Deals less damage but has more health");
String Class = scan.nextLine();
if (Class.matches(".*Fighter.*"));
Fighter user = new Fighter();
else if (Class.matches(".*Mage.*"));
Mage user = new Mage();
else if (Class.matches(".*Thief.*"));
Thief user = new Thief();
else
Human user = new Human();
user.Name();
user.Explore();
/*When I run the code, it highlights the first "user" and says "variable declaration not allowed here"
I don't know how to fix this.
*/
You've got a few spelling mistakes that might be causing problems
public static boid main (String[] args)
should be
public static void main (String[] args)
and
System.out.println("Theif: Deals less damage but has more health");
should probably be
System.out.println("Thief: Deals less damage but has more health");
Futhermore, capital case Class() and lowercase class are already things in the Java SDK as well. You should use a different variable name. I've used characterStr in my example below. Standard practice dictates that you should use camelcase for naming variables and upper case for naming Java classes. When instantiating a Class() object, people generally instantiate it as Class clazz = new Class().
Moving forward, I think you should create a super class for your different User Classes. Set up something like this:
public abstract class Character
public class Fighter extends Character
public class Thief extends Character
public class Mage extends Character
public class Human extends Character
This way, the code in your main() can use your Character() object
public static void main(String[] args)
{
// Prompt the user for the character they want
Scanner scan = new Scanner(System.in);
System.out.println("Pick a class:");
System.out.println("Fighter: Deals more damage");
System.out.println("Mage: Has more health");
System.out.println("Theif: Deals less damage but has more health");
// Get the user's response
String characterStr = scan.nextLine();
Character user; // You might have to initialize this. Did not test
if (characterStr.matches(".*Fighter.*"))
{
user = new Fighter();
}
else if (characterStr.matches(".*Mage.*"));
{
user = new Mage();
}
else if (characterStr.matches(".*Thief.*"));
{
user = new Thief();
}
else
{
user = new Human();
}
user.Name();
user.Explore();
}
First problem : You cannot declare a variable in the then of the if statement if you don't put the declaration between parenthesis. The compiler doesn't accept it.
Second problem : you should declare a single variable before the if-else-if if you want at the end call a method on the instantiated instance as you do :
user.Name();
user.Explore();
In each if you should instantiate the suitable child User class and assign the it to the user variable declared above.
In Java, method should begin with lowercase. I modified it.
The code supposes that User is the parent class and class you instantiate in condition statements are subclasses of User.
User should define a name() method and a explore() method.
User user = null;
if (Class.matches(".*Fighter.*")){
user = new Fighter();
}
else if (Class.matches(".*Mage.*")){
user = new Mage();
}
else if (Class.matches(".*Thief.*")){
user = new Thief();
}
else{
user = new Human();
}
user.name();
user.explore();
Assuming the 'user' is a player who has a 'class' (ie fighter / mage). I would make a separate player class and store that information.
class Player {
String classType; // where you would store the player's class information
int hitPoints;
}
The type of the variable has to be a common base class of all objects you potentially assign to it. Since the class Object is a base class of all other classes, you could do this:
Object user = new Fighter();
But it is probably not a good idea.
You should probably derive Fighter, Mage etc. from a base class, say Character. Instead of a base class you can also use an interface.

Using XML-derived Variables in the Main Method

so I am making a game where the player's skill damage is determined by their Skill Level and their weapon Mastery. The two values are stored in an XML document, and I am using DOM to retrieve the values, and am trying to print their sum to the console.
public class Damage {
public String skillName = "Bash"; //name of the skill
Xml config = new Xml("C:/character.xml","config");//part of the XML retrieving
Xml version = config.child("Character");//another part of the XML retrieving
int mastery = version.integer("Mastery"); //mastery of the skill
int skillLevel = version.integer("skillName");//skill level
int skillDamage = mastery + skillLevel; //adding the two values together
public static void main(String[] args) {
System.out.println(skillDamage);
}
}
When I run this code, it tells me that I can't have non-static variables in the static Main method. However, when I place the static tag before the int on the variables, it results in 0.
My question is: How can I make the variables static but still produce the sum of the two XML values? Could I somehow collect the non-static data from the XML, make it static, and then use that?
Try
System.out.println(new Damage().skillDamage);
Because you need a instance for non-static class-variables
You need to create an instance of your Damage class first, if you want to use its non-static variables/members. Put your main method like this:
public static void main(String[] args) {
Damage dmg = new Damage();
System.out.println(dmg.skillDamage);
}
I don't think you want the variables to be static.
1) Make skillDamage a public int
2) Then, just create your object in your main method:
Damage d = new Damage();
System.out.println(d.skillDamage);
It would probably be best to encapsulate skillDamage in a method, something like
public int getSkillDamage(){...}
Imagine that you have class cow. You can create instances of that class, for example berta and milka . That would mean, that you have two cows and their behaviour is based on class cow.
If you define something static it means, it is static to its class, therefore you can not define specific actions for each cow.
You should have a new class, for example "GameEngine", you should have all what you need there and you should create it with something like : GameEngine ge = new GameEngine(); and then use methods like ge.readXML();

How to use one array on 2 different classes

I have 2 classes right now, the first class has the arraylist in it. But on the second class when I try to access the arraylist it keeps giving me the red line underneath saying that the variable doesn't exist.
Here is class one...
public class BankMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
BankMain main = new BankMain();
menu();
}
public static void cardNumbers(){
ArrayList<Integer> cardNum = new ArrayList<Integer>();
Scanner cards = new Scanner(System.in);
Scanner input = new Scanner(System.in);
Scanner keyboard = new Scanner(System.in);
System.out.println("Please select a 5 digit card number");
cardNum.add(input.nextInt());
System.out.println("Thank you! You're card number is " +cardNum);
System.out.println("Type 'c' to go back to main menu.");
String value = keyboard.next();
if(value.equalsIgnoreCase("c")){
menu();
}
else if (!keyboard.equals('c')){
System.out.println("Invalid Entry!");
}
}
public static void menu(){
System.out.println("What Would you like to do today?");
System.out.println();
System.out.println("Create Account = 1");
System.out.println("Login = 2");
System.out.println("Exit = 3");
query();
}
public static void query(){
Scanner keyboard = new Scanner(System.in);
double input = keyboard.nextInt();
if (input == 2){
BankMainPart2 main2 = new BankMainPart2();
System.out.println("Please enter your 5 digit card number.");
main2.loginCard();
}
else if (input == 1){
cardNumbers();
}
else if (input == 3){
System.out.println("Thank you, have a nice day!");
System.exit(0);
}
}
}
Here is the second class...
public class BankMainPart2 {
public static void loginCard(){
if (cardNum.contains(name)) {
}
}
}
I know I haven't entered anything in the if statement yet on the second class but I'm just trying to get my array list to work on both classes.
The code looks very naive. A very simple answer to your question is
You have not declared any cardNum in BankMainPart2 as global variable or in loginCard as local variable, how do you think it will be available in the loginCard method?
ArrayList<Integer> cardNum = new ArrayList<Integer>();
is local to cardNumbers method.
How can you access it from other class?
A local variable cannot be accessed from outside the method, so first thing, make cardNum class level variable
Make the variable public if you want other classes to be able to access it directly, else make the variable private and create getter method (setter if required).
You can also send the variable when calling the method as argument
If this is class level variable, make it static and use Classname.variable.
--Edit--
As you have asked for details let me give you a quick overview of the different approaches.
A variable declared inside a method is local. as name suggest "local", no one but the method knows there is such a variable. No other method in the class knows about existence of this variable, let alone some outside class.
I say you can make it static, but static should strictly be used for class level storage, not object level. Say a list which is modified by multiple objects of the same class (I hope you know concepts of objects, else go to the basics otherwise it will not be clear). Now as per your example, I guess this is not what you want.
A public variable is generally no - no, only in few cases it will be useful (for example in android programming where performance is utmost important). Normally we will create a variable and provide getter setters. A getter or setter is used normally when we want to give access to the variable, which again does not look like what you want.
Last, the variable is private to you class, but if you want some method to do something about it, you can pass it as argument, this looks the case for you.
Step by step
take the variable out of method and add to class level, note that I removed static from method names
public class BankMain {
private ArrayList<Integer> cardNum = new ArrayList<Integer>();
// rest of code as it is
..
..
BankMain main = new BankMain();
//change
main.menu();
//no need foe static
public void cardNumbers(){
//no need here now
//ArrayList<Integer> cardNum = new ArrayList<Integer>();
Scanner cards = new Scanner(System.in);
Scanner input = new Scanner(System.in);
..
..
//public static void menu(){
public void menu(){
//send the list
//I see there are confusion at times regarding calling of static method.
//please note objectname.staticMethod() or classname.staticMethod() is one
//and same thing. Just that classname.staticMethod() is more clear
BankMainPart2.loginCard(cardNum);
}
and
public class BankMainPart2 {
public static void loginCard(ArrayList<Integer> cardNum){
if (cardNum.contains(name)) {
}
}
}
Your method, BankMainPart2.loginCard has not context of "cardNum", it doesn't know what it is (type or value).
In order for the method to be able to act on the array list, you must pass a reference to it, something like...
public class BankMainPart2 {
public static void loginCard(ArrayList<Integer> cardNum){
if (cardNum.contains(name)) {
}
}
}
make the cardnum arraylist as an instance variable in BankMain class and extend BankMain in BankMainClass2 and using reference of BankMain you would be able to access cardNum like this
Class BankMain {
public ArrayList<String> cardNum = new ArrayList<String>();
}
Class BankMain2 extends BankMain {
public void method() {
BankMain2 main = new BankMain2();
sysout(main.cardNum.size());
}
}
but the above scenario would only work when cardNum ArrayList in BankMain class is either marked public,protected or default(Nomodifier). it wouldnt work if its marked as private and other non access modifier such as static and final
You can try any one of these
1.Declare the Arraylist as public then import the first class and use the cardNum in the second class
2.Make the cardNum a static var and use it directly in second class as BankMain.cardNum
3.Pass the Arraylist as argument to the second class.
The key problem is in the the way you are trying to create your classes. Your current problem can be solved by answer given by #MadProgrammer. But you should definitly have a look into the Object Oriented Programming Concepts. This section on How to identify and design a Class? should give you some clear pointers.

Categories