Calling Code From Other Classes - java

Hi Im a begginer with Java so no complex code etc
Basically to avoid my code from getting too long i want my user to input a choice and then i have a bunch of for and elese's for what happens if they enter a certain phrase, e.g.
if(choice.equals("Fight")) {
//Grab code from fight.java/fight.class
}
else
{
if(choice.equals("Train")) {
//Grab code from train.java/train.class
}
else
so on and so forth for two other possible inputs. I just need to know how to call external code so it doesn't get too cluttered.

You should create objects of these classes.
For example:
if(choice.equals("Fight")) {
//Grab code from fight.java/fight.class
fight f = new fight();
f.foo(); // A method
}else{
if(choice.equals("Train")) {
//Grab code from train.java/train.class
train t = new train();
t.foo(); // A method
}
//...
}
Or you can try static methods like that:
public class train{
public static void foo(){
//...
}
}
Then you can use it.
if(bool_expression){
train.foo(); // foo is a static method
}

Instead of using the for else structure I would suggest using a switch statement. This will look like:
switch(choice){
case"fight":
Fight.kickHard();
break;
case"train":
Train.run();
break;
default:
Program.learn();
}
Don't forget about the break statements when using a switch. In my example I used static methods from the classes. You would probably be well served by looking further into object oriented design to see if you can come up with a more streamlined answer to your particular problem. The additional classes will need to be imported with an import statement. You will want to look into the shortcut for your IDE to do that for you, but it is a fairly elementary statement e.g import my.package.Train; etc.

If you are trying to call static methods, it would be as simple doing the following.
train.doStuff();
If the methods belong to an object you would first have to instantiate an object to access any methods on it.
Train train = new Train();
train.doStuff();
NOTE: an IDE will automatically link up the classes for you. Otherwise you have to manually import these classes first by adding "import somepackage.someclass".

First focus on different things you program can do. Place that code in a method with a name indicating its intent:
private static void doWork(){
System.out.println("Working");
}
private static void play(){
System.out.println("Playing");
}
private static void sing(){
System.out.println("Singing");
}
Now, you need to bind these to user's phrases (assuming Java 7):
switch(choice){
case: "work"
doWork();
break;
case: "play"
play();
break;
case: "sing"
sing();
break;
default:
System.out.println("Unknown choice");
}

Related

Beginner assistance with transferring information between classes

I am working on a homework assignment that takes input from a .csv file and will prompt the user for different questions pertaining to the information contained within (crime statistics).
My code is as follows and it's still really early so I just have some placeholder variables in there as I have been wracking my head trying to figure out the best approach to this problem.
import java.io.*;
public class USCrimeArray {
String crimeArray[][] = new String[21][20];
public void createCrimeArray() throws Exception{
String crimeArrayInputString;
int crimeArrayRowValue = -1;
try (BufferedReader crimeArrayInput = new BufferedReader(new FileReader("C:/Users/Joey/Documents/Crime.csv"))) {
while ((crimeArrayInputString = crimeArrayInput.readLine()) != null) {
crimeArrayRowValue++;
crimeArray[crimeArrayRowValue] = crimeArrayInputString.split(",");
}
} catch (IOException io) {
io.getMessage();
}
}
public USCrimeArray(){
String[][] thisArray = crimeArray.clone();
}
public String[][] getCrimeArray(){
return crimeArray.clone();
}
}
This is the code for my first class and if I do a deepToString inside of createCrimeArray I get the information back that I want. The constructor for USCrimeArray hasn't really been thought out yet my main question is how to write the information to the crimeArray[][] so that I can carry it back over to other classes.
Once again this test main hasn't been thought out too far because I am still struggling with why my method is not writing over the crimeArray[][] with the while loop and it is as follows:
import java.util.Arrays;
public class USCrimeClass {
public static void main(String[] args) {
USCrimeArray crimeArray = new USCrimeArray();
String[][] test = crimeArray.getCrimeArray();
System.out.println(Arrays.deepToString(test));
}
}
I know there's a lot I'm doing wrong here, but this is the end result so far after having altered everything over and over again and not making any progress. The result of the system out in this is obviously just a 21x20 array of null elements. Any help would be greatly appreciated.
You need to call createCrimeArray() in USCrimeClass
public class USCrimeClass {
public static void main(String[] args) {
USCrimeArray crimeArray = new USCrimeArray();
crimeArray.createCrimeArray();
String[][] test = crimeArray.getCrimeArray();
System.out.println(Arrays.deepToString(test));
}
}
Also,
in the constructor of USCrimeArray you are clonning the array into a local variable thisArray but never use it. this is redundant and can be safely removed.
in getCrimeArray() you are returning a clone of the array. this is not needed (unless you want to keep USCrimeArray immutable). you can just return the array itself
Instance variables
instance variables are non static class level variables (much like crimeArray).
One can consider instance variables as serving two purposes:
"details" of the problem domain of the class. For example Person class will have instance variables such as firstName and lastName that are details of one person.
"configuration" variables holding information related to the technological environment and not pertaining to the problem domain of the class. For example, one sometimes might find a class with a boolean deleted instance variable that signifies a "soft deleted" instance that is not to be presented to the user or included in calculations. the purpose behind this is to support undo of deletion.
so crimeArray is of category details of USCrimeArray. common best practice is to initialise instance variables in the class constructor, so by the time you finish creating a new instance, you have one that has full and valid details. So I would move all of the code of createCrimeArray() into the constructor.
If you need to modify an instance variable after it was initialised, then a "setter" method can be used. these have a standardized signature: public void setCrimeArray(crimeArray[][]). having a standardized signature allows your class to be used by frameworks and libraries that add functionality. For example, storing the data in a relational database, sending/recieving the data over the internet, etc.
Now, I see that the external input that is used to populate the array comes from a file. The way it is coded now, USCrimeArray can only read one specific file from predetermined file syatem location. a more flexible way would be for the class to receive the specification for external input as an argument:
public USCrimeArray(String filename) {
...
try (BufferedReader crimeArrayInput = new BufferedReader(new FileReader(filename))) {
...
}
now the same class can be used to process an array from different files.
now you can even make the file name an argument of the java program:
public class USCrimeClass {
public static void main(String[] args) {
USCrimeArray crimeArray = new USCrimeArray(arg[0]);
System.out.println(Arrays.deepToString(test));
}
}
now the same java program can process different files without need for recompile.

Search and Call object associated with string in a hashmap in java

So i'm trying to make a text game in java for a project and i have a problem in the main loop.I have the available commands in a hashmap named commands in the class CommandWords and i want to check if the user input exists in the hashmap and if it does to execute the associated object.But i can't exactly find a way.Here is my code.I understand it's probably an if but i don't know how to check.
public void play()
{
System.out.println("Welcome to the world of JZork " +player.name);
printWelcome();
boolean finished = false;
while (! finished) {
Command command = parser.getCommand();
if(command == null) {
System.out.println("I don't understand...");
}
}
}
It is possible to do it the way you said, but you would need to learn to use Java reflection. This isn't THAT hard, but you aren't going to like it.
if (command.equals("quit")) {
quit();
}
else if (command.equals("whatever")) {
whatever();
}
This isn't that elegant, but it's easy to implement.

Java - stop function from its normal run

Is there any easy way such as break for whiles to stop/skip a running function?
public void a(){
do_this();
//break the function here
do_that(); //do not load this
}
What I want to approach could be done with boolean and if statements as well, but I was wondering if there was some shortcut command in order to do this.
public void a(){
do_this();
if(1==1)
return;
do_that(); //do not load this
}
Just curious, why do you want to write such a code?
let the first function return a boolean that indicates if the calling function should move on:
public void a(){
boolean doContinue = do_this();
if(doContinue) {
do_that();
}
}
i you ALWAYS want to skip the second part, it's dead code. you could just remove it.
Always have in mind that your code should be readable for other programmers!

How to refactor a big function with many if constructs?

We have App A as main app. Now we build from it App B which uses a subset of App A's functionality.
App A stays like it is whereas app B only uses a subset of A
So I want to refactor the function without or with as little dublication as possible and with maximum readability.
So the function looks like this (it is actually longer, this is an excerpt):
class SomeClass {
Data prepareData() {
if (this.bothId==1 || this.appAid=2 /*or only relevant for appA*/) {
if(this.data==null) { /*appA*/
appAdoSmth(); /*appA*/
}
boolean merge=false; /*appA*/
if (this.data==null) { /*appA*/
merge=appAanalyze(data); /*appA*/
}
bothPrepare(merge);
} else if (bothIsRelevant()) {
if(appArelevant()) { /*appA*/
data=appAprepare(); /*appA*/
} else {
data=prepareBoth();
}
bothUpdateSomeValue();
}
}
How would you do it?
Other Answers address the general question of how to refactor code. They offer good advice, but I don't think it is what you are asking.
I think you are asking about possible refactorings of the code in your question.
It is hard to give an answer that is generally applicable, or even specifically applicable. (The sample code isn't your real code, and it is a little difficult to understand what it actually "means").
AndreasD gives one approach: break the big complicated nested if into separate methods.
Another approach is to use the Stragegy design pattern. Separate the code that is specific to each app into strategy classes. For example:
interface Strategy {
Data prepareData();
}
class GeneralStrategy implements Strategy {
Data prepareData() {
// do general preparation
}
}
class App1Strategy extends GeneralStrategy {
Data prepareData() {
// do app1-specific preparation
super.prepareData();
// do more app1-specific preparation
}
}
and so on.
I ideal world develop unit test that validates that existing implementation of your function works.
Then start changing code incrementally and run your test after every change.
It is hard to give your formal recommendation without knowing your code structure. But generally try to find duplicate code fragments, write methods that implement this logic with parameters and replace the duplicate fragments to your new method. Etc, etc.
Good luck.
Readbility can be improved by extracting some logic in separate methods. That is a refactoring method.
Data prepareData() {
if (this.bothId==1 || this.appAid=2 ) {
handleCase1(); // <- you'll find better names for the methods
} else if (bothIsRelevant()) {
handleCase2();
}
}
private void handleCase1() {
if(this.data==null) {
appAdoSmth();
}
boolean merge=false;
if (this.data==null) {
merge=appAanalyze(data);
}
bothPrepare(merge);
}
private handleCase2() {
if(appArelevant()) {
data=appAprepare();
} else {
data=prepareBoth();
}
bothUpdateSomeValue();
}
This doesn't reduce the number of if/else, of course, but it keeps the "main" method simple.
If I were you I would run a coverage report on this class. (e.g. http://ecobertura.johoop.de/ or http://www.eclemma.org/) This way Eclipse can show covered lines green and this helps you to identify the cases. With this aid it's much easier to separate green lines and pull them into methods.

How to convert my state machine to java?

Here is the normal way I would do things in C++:
class object
{
public:
enum
{
STATE_ACTIVE = 0,
STATE_INACTIVE,
OBJ_NUM_STATES,
}
int m_State;
virtual void UpdateState ()
{
switch(this->m_state)
{
case STATE_ACTIVE: /* do stuff*/ break;
case STATE_INACTIVE: /* do stuff*/ break;
}
}
}
class SpecialGameObject : public Object
{
public:
enum
{
STATE_SPECIAL_A = OBJ_NUM_STATES + 1,
STATE_SPECIAL_B,
SPECIAL_NUM_STATES,
}
virtual void UpdateState ()
{
Object::UpdateState();
switch(this->m_State)
{
case STATE_ACTIVE: /* do extra stuff */ break;
case STATE_SPECIAL_A: /* do special stuff*/ break;
case STATE_SPECIAL_B: /* do special stuff*/ break;
}
}
}
I am trying to figure out to get all of this functionality to work in java. Specifically I need working:
1) Ability for derived classes to have state values that automatically line up after the derived state values. That way I can add new state values to the base class without worrying about them overlapping the rage of state values used in any of the derived classes.
2) Ability to use the state values as cases in switch statements.
I looked into using static final ints to implement my state values. But those can't be used as case statements. Then I looked into extending enums, but that isn't allowed.
Does anyone have any suggestions for me?
Thank you
You need to implement the state pattern in Java. This might help you. Wikipedia also has a simple and easy to understand example in Java.
Is this enough to get you going?
final class GameObject {
enum State { ACTIVE, INACTIVE };
State state;
void updateState()
{
switch(state) {
case ACTIVE :
// update state
break;
case INACTIVE:
// update STATE
break;
default:
assert false : "never get here";
}
}
}
Note that in Java, enums are final so you can't extend an enum directly. (Reference this SO question.) If you really need to extend the notion of state into specialized subclasses, things are probably complicated enough that you should consider using polymorphism rather than switch statements (see also here) to get what you want. Alternatively, you could bundle the "super" state with specialized substates in a wrapper super- and sub-classes, perhaps with defined interfaces.
And, if you want to get seriously warped, you could do something like this. It's very cool that Java enums can implement interfaces, but I think this counts as a particularly ugly way of using that feature for your question...
final class GameObject {
ActiveStateful state;
interface ActiveStateful {
State activeState();
}
enum State implements ActiveStateful {
ACTIVE, INACTIVE;
public State activeState() {
return this;
}
};
enum SubState implements ActiveStateful {
SPECIAL_A(State.ACTIVE), SPECIAL_B(State.ACTIVE);
SubState(final State activeState) {
this.activeState = activeState;
}
final State activeState;
public State activeState() {
return activeState;
}
}
}
But those can't be used as case statements.
If I told you this was incorrect, that would solve your problems, yes? This is incorrect: you can switch on static final int constants.
I'd recommend using an enum and its ordinal values for switch statements. That's what enum was born for.
Please consider getting rid of switch altogether. It is a horrible abomination that should have ceased decades ago but didn’t. Read the excellent “Abandoning switch In Three (And A Bit) Steps” article for more information.

Categories