I noticed that in the below example code, when the "Scanner scan" and "String [] words" were declared, they were assigned 'null'. Why do we need to do that? Many thanks for your help! * The example code was designed to read strings from a file, with the first line of the file being the number of strings: int howMany.
int howMany;
Scanner scan = null; //why do we need to assign a 'null'?
File f;
String[] words = null; //why not use String[] words= new String []; ?
try {
f = new File(filename);
scan= new Scanner(f);
howMany = scan.nextInt();
words = new String[howMany];
for (int i = 0; i < howMany; i++) {
words[i] = scan.next();
}
} catch (IOException e) {
System.out.println(e);
}
For the first question, why initialize the Scanner to null? Assume you didn't. In your code example, this wouldn't matter much, but what if you wanted to use the Scanner object after the try block, in the catch or finally blocks, or return it from method? The Scanner might not have been initialized, since you (and the compiler) doesn't necessarily know what will happen in the try block until runtime. It's not a necessity to instantiate the Scanner to null, it is just common place to instantiate IO objects to null outside of try blocks because you will usually have to do something with that IO object outside of the try block, namely, close it.
Secondly:
"why not use String[] words= new String []; ?"
Because array initializers require an amount between the '[' and the ']' and the amount is derived from the scan.nextInt(); execution line. Why is it being initialized to null? Se the first paragraph.
It is a good philosophy/strategy to not declare objects until they are needed to limit scope, and as an extension, it is good not to initialize objects until needed. Setting either of these to null preemptively will cause more harm than good and opens you up to NPEs. Java will initialize array components, class variables and instance variables to null by default. If the variable does not fall into this category, then leave it uninitialized unless the first paragraph situation forces you to do otherwise, as the compiler will warn you if it is used without being first initialized (this is a protective mechanism for you, the developer)
So to answer your question, you don't need to do that in the given example, and probably shouldn't.
Related
I am using java and somehow have infinite inputs when I want to terminate the loop when there is a blank input
here is my code: I hope someone can explain my error
import java.util.Scanner;
public class Main1{
/*int i=0;*/
private static Customer[] getCustomer(){
Scanner scanner = new Scanner(System.in);
Customer[] customers = new Customer[100];
int i=0;
while((scanner.hasNextLine())){
customers[i++] = new Customer(i,scanner.nextDouble());
}
/*int j;
for(j=1;j<=i;j++){
customers[j] = new Customer(j,sc.nextDouble());*/
return customers;
}
public static void main(String[] args){
int j;
for(j=1;j < getCustomer().length;j++) {
/*Customer[] customer = new Customer(getCustomer());*/
System.out.println(getCustomer());
}
}
}
The hasNextLine of the Scanner class was created for situations when the Scanner is created for finite input streams, like a file. And then it's used to check if the stream has ended, in which case the program should stop asking for input.
However, System.in (a.k.a stdin, a.k.a the console) is infinite in the sense there can always be new input, hence it always has a next line and hasNextLine returns true anytime.
The condition you need to check is simply whether or not the input itself equals to the empty string, meaning the user entered a blank line.
You should not create a new Scanner each time you call getCustomer). For that matter, since getCustomer() gets a list of customers, it should only be called once, outside the loop.
Your getCustomer() method should create a List instead of a fixed length array,and it should return that list. And as #neo says, just exit the input loop whenever the user inputs an empty line.
Then your loop in main() would iterate through the list and print the customers. Something like
for ( Customer c : customers ) {
System.out.println( c );
}
This could also be done with a single statement using streams.
This, of course, assumes that Customer has a toString() override that returns the appropriate String to identify the Customer.
I have a text file and that file lists all the operations that can be performed on a Pump Class.
example of the content of text file
Start PayCredit Reject Start PayCredit Reject TurnOff
....
.... so on.
These are the methods of the Pump class(Start(), Reject() etc)
I need to write a code where I can Read these method from the file one by one and execute them.
public static void main(String[] args) throws IOException
{
Pump gp= new Pump();
File file=new File("C:\\Users\\Desktop\\checker\\check.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line=null;
while((line=br.readLine())!=null)
{
String words[]=line.split(" ");
for(int i=0;i<words.length;i++)
{
String temp=words[i]+"()";
gp.temp; //compilation error
}
}
}
Could you tell me how can I achieve this functionality.
If you're not so familiar with reflection, maybe try using org.springframework.util.ReflectionUtils from the Spring Framework project?
The code would go something like this:
Pump gp = new Pump();
....
String temp = // from text file
....
Method m = ReflectionUtils.findMethod(Pump.class, temp);
Object result = ReflectionUtils.invokeMethod(m, gp);
You would need to use reflection to invoke the methods at runtime. Here is a simple example that assumes that all methods do not take any parameters.
Class<? extends Pump> pumpClass = gp.getClass();
String methodName = words[i];
Method toInvoke = pumpClass.getMethod(methodName);
if (null != toInvoke) {
toInvoke.invoke(gp);
}
First of all be aware that Java is not interpreted at runtime. So you can't do it this way.
If you already have the methods such as Start PayCredit Reject TurnOff and so on you can do it in the following way:
for(int i=0;i<words.length;i++)
{
String temp=words[i];
if (temp.equals("Start") gp.Start();
else if (temp.equals("PayCredit") gp.PayCredit();
...
}
use a switch case
for(int i=0;i<words.length;i++) {
String temp=words[i];
switch(temp) {
case "Start":
gp.start();
break;
case "PayCredit":
gp.PayCredit();
break;
}
}
You can use reflection to do this, e.g.
String line=null;
Method method = null;
while((line=br.readLine())!=null)
{
String words[]=line.split(" ");
for(int i=0;i<words.length;i++)
{
String temp=words[i];
method = getClass().getMethod(temp);
method.invoke(this);
}
}
That's assuming you want to call the method on this, of course, and that it's an instance method. Look at Class.getMethod and related methods, along with Method itself, for more details. You may want getDeclaredMethod instead, and you may need to make it accessible.
I would see if you can think of a way of avoiding this if possible though - reflection tends to get messy quickly. It's worth taking a step back and considering if this is the best design. If you give us more details of the bigger picture, we may be able to suggest alternatives.
My java program takes input from the user on the command line. The user has a choice: he may either specify a plain-text file as input with the -inputfile option, or he may leave this option unspecified, in which case the program takes input from System.in. (I've observed this behavior in some programs that come pre-installed with my Ubuntu distro, so I infer that it is acceptable practice.)
So I make a BufferedReader (inBR)that reads from the file, if provided, and a Scanner (inScanner) that reads from System.in otherwise. Only one of these objects is actually instantiated, the other is left as null. Later on, when the program reads a line from input, I have the following code:
String line;
if (inBR != null) {
line = inBR.readLine(); (1)
} else {
line = inScanner.nextLine(); (2)
}
Which gives me the compile time errors variable inBR might not have been initialized and variable inScanner might not have been initialized at lines (1) and (2), respectively.
What is the acceptable solution here? I've considered, "initialize the variable that's supposed to be null as an Object to shut up the compiler." But this is just a hack; surely there's a better way.
Also, why isn't this a runtime exception, as a NullPointerException?
EDIT: inScanner.readLine() => inScanner.nextLine()
Declaring them this way would avoid the compilation error :
BufferedReader inBR = null;
Scanner inScanner = null;
Of course you still have to give them actual values before accessing them, or you'll get NullPointerException.
In java all variables that are used must be initialized at some point.
public void example(){
String name;
if(name == null) return null;
}
In the above example the variable name has not been initialized. There are several ways to solve this problem:
public void example1(){
String name = null;
if(name == null) return null;
}
This would solve the problem.
This would also solve the problem
public void exapmle2(){
String name = "";
if(name == null) return null;
}
Make the condition whether or not a file is provided. For example, if a file is provided, create the buffered reader and set line immediately. Otherwise, create a scanner and set the line.
Let me clarify the question I am asking. I have a java program I am working on that takes input from the keyboard via a readline library called JLine2. The library takes the entire line types as a command instead on breaking it up into space separated commands and arguments. What I am looking for is a safe way to break up the string that is passed as input.
I have tried using an array but since I am in the early stages of concept I don't yet know how many arguments my largest command will have so using a pre-initialized array I don't think will work. The problem I have ran into is when I check for null values in the array or when I check to see if a particular command or argument is present. Java keeps throwing an exception about the array index being out of scope or something. Because the array does not actually have a value for say array index 1 which is an argument to command in array index 0.
So what I am looking for is a way to take a string and safely split it into parts without having Java yelling at me when and array exception has occurred.
Here is the very slim code I can provide...
ConfigShell.class
package shell;
import java.io.IOException;
import configFS.ConfigFS;
import jline.console.ConsoleReader;
public class ConfigShell {
private ConfigFS config;
public ConfigShell() throws IOException {
config = new ConfigFS();
}
public void init() throws IOException {
ConsoleReader console = new ConsoleReader();
// When the program starts we want to be placed at / (root).
console.setPrompt(">> ");
// In this case an infinite loop is better than a loop based on whether line is equal to null.
// This allows line to be equal to null and still stay inside the shell.
while (true) {
String line = console.readLine();
if (line != null) {
// If pre-initialize the array I can check for null as a value for an array index.
// If I did this at time I needed the array and there were not enough index occupied the system would return an exception.
String[] cmdArgs = new String[4];
// We need to split up the incoming line because JLine2 does not do it for me.
// This allows me to evaluate the entire command piece by piece rather all at once.
cmdArgs = line.split("\\s+");
if (cmdArgs[0] != null && cmdArgs[0].equals("add")) {
if (cmdArgs[1] != null && cmdArgs[1].equals("server")) {
if (cmdArgs[2] != null) {
config.addServer(cmdArgs[2]);
System.out.println("Added server " + cmdArgs[2] + " to the configuration successfully.");
}
}
}
if (cmdArgs[0].equals("exit")) {
System.exit(0);
}
}
}
}
}
Note for testing: My Start.class main method makes a call to the init method in the above file.
You can do:
String cmdArgs = line.split("\\s+");
and then, before accessing any particular index, check the size of the array so that you do not get ArrayIndexOutOfBoundException
Something like this:
if(cmdArgs.length>=2){
//It means you have at least 2 elements
//Now its safe to access cmdArgs[0] and cmdArgs[1]
}
If all your problem is to have a storage for a variable number of strings you can use ArrayList<String> object.
You declare it like ArrayList<String> as = new ArrayList<String>();
Then when you split something from your command string you will simply use add method:
as.add(yourString);
If you need to retrieve a particular element of the ArrayList you can use its get method:
as.get(0);
You can process all elements with for each loop:
for(String str: as) {
println(str):
}
Have a look here for info and here for an example.
As I think you can use StringTokenizer class and its methods for your requirement.
see the sample code below:
if(line!=null)
{
StringTokenizer st=new StringTokenizer(line);// by default it takes space as delimiter....you can use as required as second argument in constructor...
while(st.hasMoreTokens())
{
String token1=st.nextToken();
// do your stuffs here..........
// I don't know exactly about your required logic here......
/* if(token1.equals("add"))
{
String token2=st.nextToken();
if(token2.equals("server"))
{
String token3=st.nextToken();
config.addServer(token3);
System.out.println("Added server " + token3 + " to the configuration successfully.");
}
}
*/
}// while closing...
}// outer if closing...
Or as PM 77-1 told you can use ArrayList. But as my opinion LinkedList should be a better option here.
A while back, I was working on a program that hashed values into a hashtable (I don't remember the specifics, and the specifics themselves are irrelevant to the question at hand). Anyway, I had the following code as part of a "recordInput" method:
tempElement = new hashElement(someInt);
while(in.hasNext() == true)
{
int firstVal = in.nextInt();
if (firstVal == -911)
{
break;
}
tempElement.setKeyValue(firstVal, 0);
for(int i = 1; i<numKeyValues;i++)
{
tempElement.setKeyValue(in.nextInt(), i);
}
elementArray[placeValue] = tempElement;
placeValue++;
} // close while loop
} // close method
This part of the code was giving me a very nasty bug -- no matter how I finagled it, no matter what input I gave the program, it would always produce an array full of only a single value -- the last one.
The problem, as I later determined it, was that because I had not created the tempElement variable within the loop, and because values were not being assigned to elementArray[] until after the loop had ended -- every term was defined rather as "tempElement" -- when the loop terminated, every slot in the array was filled with the last value tempElement had taken.
I was able to fix this bug by moving the declaration of tempElement within the while loop. My question to you, Stackoverflow, is whether there is another (read: better) way to avoid this bug while keeping the variable declaration of tempElement outside the while loop.
Why would you want to keep the variable declaration outside the while loop? Anyway, you can, as long as you assign it to a new hashElement each time:
hashElement tempElement;
while (/*...*/) {
tempElement = new hashElement();
//...
It's certainly not "better" though. Scope your variables as narrowly as possible, in general.
This is not about declaration of the variable, but about the objects you create. Arrays in java only hold references to objects, so if you actually want to have distinct objects in the array, you need to create them with new somewhere in the loop.
tempElement = new WhateverClass();
Element tempElement;
while(condition){
tempElement = new HashElement();
//do more stuff
elementArray[index] = tempElement;
}