Search and Call object associated with string in a hashmap in java - 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.

Related

asking user for input valid command in java

I am developing my own shell(command prompt). [When
a user enters a built-in command, the shell is required to search and execute the respective code accordingly.]
I have created my code using command split, and command parameters in order to store my commands. but one thing I'm confused about is that making a command that is not in the list.
I think of using if statement to print invalid comment (for example)
if (command!="exit")||(command!="about")||(command!="date")||(command!="time")||(command!="hist")||(command!="notepad")
||(command!="")||(command!="hist -h")||(command!="hist -l")||(command!="c"){
System.out.println("invalid command");
}
but this statement is way too much if there are tons of command line.. so is there an easy way of implementing it !?
If this java and all commands are Strings and input command is also a String you can simplify what you are trying to do by creating a list of valid commands and do a contains check.
List<String> validCommands = Arrays.asList("exit", "about", "date");
if (!validCommands.contains(command)) {
System.out.println("invalid command");
}
That being said there are better ways to maintain a list of valid command outside java program such as properties file and load list of valid commands from that file. This will make your program more maintainable.
Use a Map<String, Command>, to keep track of the available commands. If the command is not in the map then it's invalid. For example:
public class Shell {
private final Map<String, Command> supportedCommands;
public Shell(Map<String, Command> supportedCommands) {
this.supportedCommands = supportedCommands;
}
public void execute(String command, String[] args) {
Command c = supportedCommands.get(command);
if (c == null) {
System.out.println("invalid command");
} else {
c.execute(args);
}
}
public interface Command {
public void execute(String[] args);
}
}

Java Loop InputStream until boolean = false

I have this input stream that checks if I have a certain CAD file open or not. I am doing this by using an input stream to run a tasklist command with the name I want to check. I currently have a boolean that returns true if the specific CAD file isn't open. If the CAD file is open, it returns false. However, I want it to be able to loop this until the CAD file is open because as of right now I have to keep running it in order for it to work. I also need to be able to check this boolean from a separate class. I have it in my main right now so i could test it. My code looks like this...
public class AutoCadCheck {
public static void main(String[] argv) throws Exception {
String notOpen = "INFO: No tasks are running which match the specified criteria";
StringBuilder textBuilder = new StringBuilder();
String command = "tasklist /fi \"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]";
int i;
InputStream myStream = Runtime.getRuntime().exec(command).getInputStream();
while ((i = myStream.read()) != -1) {
textBuilder.append((char) i);
}
String output = textBuilder.toString();
boolean logical = output.contains(notOpen);
if (logical) {
System.out.println("DWG Not Open");
} else {
System.out.print(output);
}
myStream.close();
}
}
My other class is going to have an 'if statement' that checks whether my boolean "logical" is false, and if so, print something. I have tried every possible method I could think of, but I cannot get it to function the way I want it to. Every other thing I found involving looping an inputstream didn't really apply to my situation. So hopefully someone can help me out in achieving what I want to do.
I would start by moving everything out of main and into a different class. This will make retrieving values and calling specific functions easier. Then create an object of that class in main. Once that is done, I'd create a get method for the boolean variable. Now to focus on the loop. Once the object is created in main, create a conditional loop inside of main which calls the function you need until a different condition is met. This condition might be met once the file is open. After the condition is met, it exits to another loop that relies on another conditional, such as user input.
public class AutoCadCheck {
public static void main(String[] argv) throws Exception {
AutoCadFile file = new AutoCadFile();
//loop 1
//Some conditional so the program will
//continue to run after the file has been found.
// while(){
//loop 2
//check to see if the file is open or not
//while(logical){
//}
//}
}
}
Other class
import java.io.IOException;
import java.io.InputStream;
public class AutoCadFile {
private String notOpen;
private StringBuilder textBuilder;
private String command;
private int i;
private InputStream myStream;
private String output;
private boolean logical;
public AutoCadFile() {
notOpen = "INFO: No tasks are running which match the specified criteria";
textBuilder = new StringBuilder();
command = "tasklist /fi \"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]";
output = textBuilder.toString();
logical = output.contains(notOpen);
try {
myStream = Runtime.getRuntime().exec(command).getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void checkForFileOpen() {
try {
while ((i = myStream.read()) != -1) {
textBuilder.append((char) i);
}
if (logical) {
System.out.println("DWG Not Open");
} else {
System.out.print(output);
}
myStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean getFileBoolean() {
return logical;
}
}
My other class is going to have an if statement that checks whether my boolean logical is false ...
Well, logical is a local variable within a method. So no code in another class is going to be able to see it.
There are two common approaches to this kind of thing:
Make the variable (i.e. logical) a field of the relevant class. (Preferably NOT a static field because that leads to other problems.)
Put your code into a method that returns the value you are assigning to logical as a result.
From a design perspective the second approach is preferable ... because it reduces coupling relative to the first. But if your application is tiny, that hardly matters.
I can see a couple of other significant problems with your code.
When you use exec(String), you are relying on the exec method to split the command string into a command name and arguments. Unfortunately, exec does not understand the (OS / shell / whatever specific) rules for quoting, etcetera in commands. So it will make a mess of your quoted string. You need to do the splitting yourself; i.e something like this:
String[] command = new String{} {
"tasklist",
"/fi",
"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]"
};
Your code potentially leaks an input stream. You should use a "try with resource" to avoid that; e.g.
try (InputStream myStream = Runtime.getRuntime().exec(command).getInputStream()) {
// do stuff
} // the stream is closed automatically ... always

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!

Calling Code From Other Classes

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");
}

Java: prebuild flag to check pars not NULLs?

Currently, I use a very conservative way to stop malfunctioing code. It is annoying at the time of a change when I have to change the checker parts as well.
if(ds==null||s==null||maxDs==null)
{
System.out.println("NULL in getDirs(ds[],s,maxDs)");
System.exit(9);
}
So is there some prebuild-ready Null checker for pars in the API?
Does Java build some ready table for Parameters? Perhaps similar to Stdin argv[].
If so, where can I find all automatically build tables like argv[]?
Wanna-check-for-parameters
for(Object p:pars)
{
if(p.isNull())
{
System.out.println("Lollipop arg your pars are in Lava!");
System.exit(9);
}
}
I'm not aware of anything built in, but it should be possible to write your own annotation processet to inject some suitable code. It seems possible that only some methods need a null check, so having the control that annotations would give could be useful.
#ParamNotNull
public void myMethod(X anX, Y aY) { ...
public void myTolerantMethod(X couldbeNull) { ...

Categories