In the following code the constructor is not initializing the numFile Scanner. I added the contents of the constructor to the main method to make it work. If I do not do this a java.lang.NullPointerException is thrown. Would someone mind explaining why? Also, do I need to throw an IOException on the constructor?
Thanks for any helpful advice.
Tony
import java.io.*;
import java.util.Scanner;
public class CountPositiveIntegers {
static Scanner numFile;
static String fileName; // the name of the file in which the integers are stored
static int number; // holds the current number being read
static int counter; // a counter used to sum the number of positive integers
public CountPositiveIntegers() throws IOException {
fileName ="D:\\Java\\Source\\numFile.dat";
System.out.println("File Name: " + fileName);
numFile = new Scanner(new FileReader(fileName));
number = 0;
counter = 0;
}
public static void main(String[] args) throws FileNotFoundException {
// numFile is not being initializing in the constructor
fileName = "D:\\Java\\Source\\numFile.dat";
numFile = new Scanner(new FileReader(fileName));
number = 0;
counter = 0;
if (numFile.hasNext()) { // check to see if there are any values in the file
while (numFile.hasNextInt()) { // reads in integers
number = numFile.nextInt();
if (number % 2 == 0 & number != 0) {
counter++;
}
}
numFile.close(); // close the file
// print to screen the number of even integers stored in the file
System.out.println("There are " + counter
+ " even numbers in this file");
} else {
System.out.println("The file is empty.");
}
System.exit(0); // cleanly exit the program
}
}
You must explicitly call the constructor to have it work. (You never create a new CountPositiveIntegers()).
In fact you use only static variables, the constructor is not called, and such an object would have no non-static fields. An example of Object Oriented programming:
public class CountPositiveIntegers {
Scanner numFile;
String fileName; // the name of the file in which the integers are stored
public CountPositiveIntegers(String fname) throws IOException {
fileName = fname;
System.out.println("File Name: " + fileName);
numFile = new Scanner(new FileReader(fileName));
}
public static void main(String[] args) throws FileNotFoundException {
try {
CountPositiveIntegers obj = new CountPositiveIntegers("D:\\Java\\Source\\numFile.dat");
int number = 0; // holds the current number being read
int counter = 0; // a counter used to sum the number of positive integers
if (obj.numFile.hasNext()) { // check to see if there are any values in the file
while (obj.numFile.hasNextInt()) { // reads in integers
number = obj.numFile.nextInt();
if (number % 2 == 0 & number != 0) {
counter++;
}
}
obj.numFile.close(); // close the file
// print to screen the number of even integers stored in the file
System.out.println("There are " + counter
+ " even numbers in this file");
} else {
System.out.println("The file is empty.");
}
System.exit(0); // cleanly exit the program
} catch (IOException ex) {
Logger.getLogger(CountPositiveIntegers.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I believe that the problem is that when your program starts up, it does not create a new instance of the class in which main is executed and instead just runs the code in main. Since your initialization code is in your constructor, it's never actually run, because you don't create an instance of the main class.
To fix this, I would strongly suggest having main create a new instance of the class that main resides in, then perform all your operations on that object, rather than making everything static and just performing the operations in main directly. Your current approach is not particularly good design.
Hope this helps!
Where is your CountPositiveIntegers class object.
You need to call your constructor explicitly otherwise a default constructor will be called by the compiler.
new CountPositiveIntegers();
The constructor will not be invoked unless you actually call it. The main method does not call the constructor implicitly because it is a static method.
Related
I am making a program with two classes, one to create methods and the other as the tester class. I am having difficulties assigning the input to a new variable, which needs to be used to invoke the methods from the other class.
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
int obj = new NumberUtility(0);
System.out.println("Enter a number. Enter 0 to end");
obj = scan.nextInt();
As example here is the beginning of the other class
public class NumberUtility {
int n = 0;
public NumberUtility(int n) {
getN();
isEven();
isOdd();
}
public int getN() {
return n;
}
public boolean isEven() {
if((n % 2 == 0)) {
return true;
} else
return false;
}
My code is incomplete elsewhere but that is the main issue I have been trying to work around. Since if I set it to an int, it won't work. Sorry if this is a stupid question, I am new to java coding.
With this line:
int obj = new NumberUtility(0);
you are attempting to assign a new NumberUtility object to the variable obj which is of type int. You cannot do that! That's like trying to create a doghouse, and then shoving your dog into a birdhouse. They're just not compatible.
As well, later, you try to reassign obj to the result of scan, which would work, but probably not what you want, as obj is still an int:
obj = scan.nextInt();
I think what you want to do is something like the following:
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
System.out.println("Enter a number. Enter 0 to end");
// Read a number from the scanner
int number = scan.nextInt();
// Create a new NumberUtility from this primitive integer
NumberUtility obj = new NumberUtility(number);
System.out.println("Even? " + obj.isEven());
By the way, you can simplify your isEven method as well:
public boolean isEven() {
return (n % 2 == 0);
}
Edit: I see I'm not done yet.
In the NumberUtility class, you have defined a constructor for the class:
public NumberUtility(int n) {
getN();
isEven();
isOdd();
}
This seems like an odd thing to do. You are ignoring the input (int n) and then calling all the methods of the class which don't really do much.
I think you want your constructor to be something like this:
public NumberUtility(int input_n) {
// Save the constructor's input parameter to the member field 'n'
this.n = input_n;
}
I'm trying to learn about exception handling. I can't seem to get
String[] a = names(scnr); To throw an out of bounds exception when it goes beyond 3 elements. I know, most people hate the out of bounds error and I'm trying to make it happen and for the life of me I cannot figure out what I'm doing wrong. Been at it all day and googled all kinds of stuff. But I cannot seem to find exactly what I'm looking for. So I could use some help and perspective.
So I'm inputting a full string that I'm delimiting (trim and splitting) based on commas and spaces and then the pieces are being stored into an array (String []name), then passed to main to be output with String[] a. So it's not erroring when I go beyond 3 elements no matter how I do it. I can just not display anything beyond a[4]. But that's not really what I'm trying to do. Its my first java class so be gentle haha.
Any suggestions?
import java.util.*;
public class ReturnArrayExample1
{
public static void main(String args[])
{
Scanner scnr = new Scanner(System.in);
String[] a = names(scnr);
for (int i = 0; i < 3; i++)
{
System.out.println(a[i] + " in index[" + i + "].");
}
scnr.close();
}
public static String[] names(Scanner scnr)
{
String[] name = new String[3]; // initializing
boolean run = true;
do
{
try
{
System.out.println("Enter 3 names separated by commas ',':(Example: keith, mark, mike)");
String rawData = scnr.nextLine();
if(rawData.isEmpty())
{
System.err.println("Nothing was entered!");
throw new Exception();
}
else
{
name = rawData.trim().split("[\\s,]+");
run = false;
}
}
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println("Input is out of bounds!\nUnsuccessful!");
}
catch(Exception e)
{
System.err.println("Invalid entry!\nUnsuccessful!");
}
}
while(run == true);
System.out.println("Successful!");
scnr.close();
return name;
}
}
If I understand you correctly, you want to throw an ArrayOutOfBoundsException if the names array does not contain exactly 3 elements. The following code is the same as the one you wrote with an if-statement to do just that.
import java.util.*;
public class ReturnArrayExample1
{
public static void main(String args[])
{
Scanner scnr = new Scanner(System.in);
String[] a = names(scnr);
for (int i = 0; i < 3; i++)
{
System.out.println(a[i] + " in index[" + i + "].");
}
scnr.close();
}
public static String[] names(Scanner scnr)
{
String[] name = new String[3]; // initializing
boolean run = true;
do
{
try
{
System.out.println("Enter 3 names separated by commas ',':(Example: keith, mark, mike)");
String rawData = scnr.nextLine();
if(rawData.isEmpty())
{
System.err.println("Nothing was entered!");
throw new Exception();
}
else
{
name = rawData.trim().split("[\\s,]+");
if (name.length != 3) {
throw new ArrayIndexOutOfBoundsException();
}
run = false;
}
}
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println("Input is out of bounds!\nUnsuccessful!");
}
catch(Exception e)
{
System.err.println("Invalid entry!\nUnsuccessful!");
}
}
while(run == true);
System.out.println("Successful!");
scnr.close();
return name;
}
}
If you want java to throw an ArrayIndexOutOfBoundException you have to preserve the created names instance and let java copy the array into your names array:
String[] names=new String[3];
String[] rawElements=rawData.trim().split("[\\s,]+");
System.arraycopy(rawElements, 0, names, 0, rawElements.length);
output:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at stackoverflow.OutOfBound.main(OutOfBound.java:8)
As far as I understand, you are expecting an exception (ArrayIndexOutOfBoundsException) to the thrown at line
name = rawData.trim().split("[\\s,]+");
with an argument that the size of array (name) is fixed to 3, and when if the input is beyond 3 then the exception must be thrown; which is not the case.
The reason is in the way assignment happens in java. When you declare String[] name = new String[3];, then an object is created in java heap and its reference is assigned to variable name which is in stack memory.
And when this line name = rawData.trim().split("[\\s,]+"); gets executed then a new array object is created in heap and the variable name starts pointing to the newly created array object on heap. Note: the old object will get available for garbage collection after some time.
This eventually changes the length of the array variable (name) and you do not get any ArrayIndexOutOfBoundsException.
You can understand this more clearly by printing the object on console, like System.out.println(name); after its initialisation and post its assignment.
I will also suggest you to refer this link (https://books.trinket.io/thinkjava2/chapter7.html#elements) to understand how array are created, initialised and copied etc..
Code with system.out commands (for understanding)
import java.util.Scanner;
public class ReturnArrayExample1 {
public static void main(String args[]) {
Scanner scnr = new Scanner(System.in);
String[] a = names(scnr);
System.out.println("Variable (a) is referring to > " + a);
for (int i = 0; i < 3; i++) {
System.out.println(a[i] + " in index[" + i + "].");
}
scnr.close();
}
public static String[] names(Scanner scnr) {
String[] name = new String[3]; // initializing
System.out.println("Variable (name) is referring to > " + name);
boolean run = true;
do {
try {
System.out.println("Enter 3 names separated by commas ',':(Example: keith, mark, mike)");
String rawData = scnr.nextLine();
if (rawData.isEmpty()) {
System.err.println("Nothing was entered!");
throw new Exception();
} else {
name = rawData.trim().split("[\\s,]+");
System.out.println("Now Variable (name) is referring to > " + name);
run = false;
}
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Input is out of bounds!\nUnsuccessful!");
} catch (Exception e) {
System.err.println("Invalid entry!\nUnsuccessful!");
}
} while (run == true);
System.out.println("Successful!");
scnr.close();
return name;
}
}
I you want to throw exception when input is more than 3 then there are many ways to do it. One suggestion from #mohamedmoselhy.com is also decent.
I am new here so please show some patience. I am trying to read the data from an external file and store the info in 2 arrays.
The file looks like this:
0069 723.50
0085 1500.00
0091 8237.31
I am using 2 scanners to read the input and I think they work ok because when I try to print, the result looks ok.
My first problem is that I am able to read the first numbers on the list using nextInt(), but cannot use nextDouble() for the double ones as I get the "java.util.InputMismatchException" message. For that reason I read it as a String. The part with the other two scanners is supposed to do what the first parts should do, for a different input file, but the problem is the same.
My next and biggest problem, until now, is that am not able to store the values from the two columns in two distinct arrays. I have tried several ways (all commented) but all fail. Please help and thanks.
Here is my code:
import ui.UserInterfaceFactory;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Scanner;
import ui.UIAuxiliaryMethods;
public class Bank {
static final int MAX_NUMBER_OF_ACCOUNTS = 50;
PrintStream out;
Bank(){
UserInterfaceFactory.enableLowResolution(true);
out = new PrintStream(System.out);
}
void readFiles(){
Scanner balanceFile = UIAuxiliaryMethods.askUserForInput().getScanner();
while(balanceFile.hasNextLine()){
String balance_Line = balanceFile.nextLine();
Scanner accountsFile = new Scanner(balance_Line);
int account = accountsFile.nextInt(); //works
out.printf("%04d ",account);
/*int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS]; //does not store the values properly
int account = accountsFile.nextInt();
for(int j=0; j < accounts_array.length; j++){
accounts_array[j] = account;
}*/
/*int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS]; //java.util.InputMismatchException
for(int j=0; j < accounts_array.length; j++){
accounts_array[j] = accountsFile.nextInt();
//out.printf("%04d \n",accounts_array[j]);
}*/
String balance = accountsFile.nextLine(); //problem declaring balance as a double
out.printf("%s\n",balance);
/*String [] balance_array = new String [MAX_NUMBER_OF_ACCOUNTS]; //java.util.NoSuchElementException
for(int j=0; j < balance_array.length; j++){
accountsFile.useDelimiter(" ");
balance_array[j] = accountsFile.next();
//out.printf("%04d \n",accounts_array[j]);
}*/
}
Scanner mutationsFile = UIAuxiliaryMethods.askUserForInput().getScanner();
while(mutationsFile.hasNext()){
String mutation_Line = mutationsFile.nextLine();
Scanner mutatedAccountsFile = new Scanner(mutation_Line);
int mutated_account = mutatedAccountsFile.nextInt();
out.printf("%04d ",mutated_account);
int action = mutatedAccountsFile.nextInt(); //deposit or withdrawal
/*if (action == 1){
}else{
}*/
out.printf(" %d ",action);
/*Double amount = mutatedAccountsFile.nextDouble();
out.printf(" %5.2f ",amount);*/
String amount = mutatedAccountsFile.nextLine();
out.printf("%s\n",amount);
}
}
void start(){
new Bank();readFiles();
}
public static void main(String[] args) {
new Bank().start();
}
}
The InputMismatchException occurs because you try to read a double using the nextInt() function. To solve this issue, you can first read the tokens as Strings using the next() function and convert them appropriately.
while(mutationsFile.hasNext()){
mutation_Line = mutationsFile.next();
if(mutation_Line.indexOf(".") == -1)
//token is int
else
//token is double
}
Since you already know what the contents of the two columns are, you can store the integers and doubles in two lists and then, if you want, get them into an array.
List<Integer> intList = new ArrayList<Integer>();
List<Double> doubleList = new ArrayList<Double>();
Now replace the if statements in the first snippet with this:
if(mutation_Line.indexOf(".") == -1)
intList.add(new Integer(Integer.parseInt(mutation_Line)));
else
doubleList.add(new Double(Double.parseDouble(mutation_Line)));
In the end, you can get them into arrays:
Object[] intArr = intList.toArray(),
doubleArr = doubleList.toArray();
//display the contents:
for(int i=0; i<intArr.length; i++)
out.printf("%04d\t%.2f\n", Integer.parseInt(intArr[i].toString()),
Double.parseDouble(doubleArr[i].toString()));
OUTPUT:
0069 723.50
0085 1500.00
0091 8237.31
First off, you don't need to use 2 scanners. The Scanner object is simply reading your file, one scanner is plenty to accomplish the task of reading a file.
If you're trying to read the integers/doubles from file and are having trouble with nextInt() and nextDouble(), consider a different approach to parsing (e.g. parse the line into a string, split the line into 2 parts based on a space character, then trim both resulting strings and convert to respective integers/doubles).
Now back to the Scanner parsing the two values, remember first that when you use a next() or nextInt(), etc. those methods consume the next respective token. So parsing a line as a string from the file into another Scanner object is redundant and unnecessary in this case.
If you know your max number of accounts, and it's simply 50, then go ahead an allocate that prior to the while loop.
Here's an alternative approach with the code you posted.
public class App {
static int MAX_NUMBER_OF_ACCOUNTS = 50;
static PrintStream out;
static void readFiles() {
Scanner balanceFile = null;
try {
balanceFile = new Scanner(new File("C:\\Users\\Nick\\Desktop\\test.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (balanceFile == null)
return;
int [] accounts_array = new int [MAX_NUMBER_OF_ACCOUNTS];
double [] balance_array = new double [MAX_NUMBER_OF_ACCOUNTS];
int currentIndex = 0;
while (balanceFile.hasNextLine()) {
int account = balanceFile.nextInt();
double balance = balanceFile.nextDouble();
System.out.print("acc = " + account + " ");
System.out.println("bal = " + balance);
//out.printf("%04d ", account);
accounts_array[currentIndex] = account;
//out.printf("%s\n", balance);
balance_array[currentIndex] = balance;
currentIndex++;
}
balanceFile.close();
}
static void start() {
readFiles();
}
public static void main(String[] args) {
start();
}
}
Please note the excessive use of static could also be avoided in the future, but for the sake of the example it spread like the plague.
As you can see in the logic leading up to the while loop, the scanner object is made from a file I copied your example data into a file on my desktop. The arrays are allocated prior to the while loop (note: see #progy_rock and their use of ArrayList's - may help improve your code in the long run). And finally, note the index count to move the position along in the array to which you are inserting your lines to.
I would like to start off by saying that if this is common knowledge, please forgive me and have patience. I am somewhat new to Java.
I am trying to write a program that will store many values of variables in a sort of buffer. I was wondering if there was a way to have the program "create" its own variables, and assign them to values.
Here is an Example of what I am trying to avoid:
package test;
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
int inputCacheNumber = 0;
//Text File:
String userInputCache1 = null;
String userInputCache2 = null;
String userInputCache3 = null;
String userInputCache4 = null;
//Program
while (true) {
Scanner scan = new Scanner(System.in);
System.out.println("User Input: ");
String userInput;
userInput = scan.nextLine();
// This would be in the text file
if (inputCacheNumber == 0) {
userInputCache1 = userInput;
inputCacheNumber++;
System.out.println(userInputCache1);
} else if (inputCacheNumber == 1) {
userInputCache2 = userInput;
inputCacheNumber++;
} else if (inputCacheNumber == 2) {
userInputCache3 = userInput;
inputCacheNumber++;
} else if (inputCacheNumber == 3) {
userInputCache4 = userInput;
inputCacheNumber++;
}
// And so on
}
}
}
So just to try to summarize, I would like to know if there is a way for a program to set an unlimited number of user input values to String values. I am wondering if there is a way I can avoid predefining all the variables it may need.
Thanks for reading, and your patience and help!
~Rane
You can use Array List data structure.
The ArrayList class extends AbstractList and implements the List
interface. ArrayList supports dynamic arrays that can grow as needed.
For example:
List<String> userInputCache = new ArrayList<>();
and when you want to add each input into your array like
if (inputCacheNumber == 0) {
userInputCache.add(userInput); // <----- here
inputCacheNumber++;
}
If you want to traverse your array list you can do as follows:
for (int i = 0; i < userInputCache.size(); i++) {
System.out.println(" your user input is " + userInputCache.get(i));
}
or you can use enhanced for loop
for(String st : userInputCache) {
System.out.println("Your user input is " + st);
}
Note: it is better to put your Scanner in your try catch block with resource so you will not be worried if it is close or not at the end.
For example:
try(Scanner input = new Scanner(System.in)) {
/*
**whatever code you have you put here**
Good point for MadProgrammer:
Just beware of it, that's all. A lot of people have multiple stages in their
programs which may require them to create a new Scanner AFTER the try-block
*/
} catch(Exception e) {
}
For more info on ArrayList
http://www.tutorialspoint.com/java/java_arraylist_class.htm
I have written a simple program in the NetBeans IDE using Java. After making a few changes to the main method this morning, the console does not print anything when I run the program. I simply want it to reach startMenus(sc). EDIT: I have now put in a few System.out.println() and it does not reach "Blah2" which is right after my first loop...
public class Calculator {
public static int[] NUMBERS; //global value for the array
public static void main(String[] args) throws FileNotFoundException {
File file = new File("data.txt");
Scanner sc = new Scanner(file);
System.out.println("Blah1");
int counter = 0;
while (sc.hasNextInt()) {
counter = counter++;
}
System.out.println("Blah2");
int lenth = counter;
NUMBERS = new int[lenth];
System.out.println("Blah3");
sc.close();
File file2 = new File("data.txt");
Scanner sc2 = new Scanner(file2);
System.out.println("Blah4");
int i = 0;
while (sc2.hasNextInt()) {
NUMBERS[i] = sc2.nextInt();
++i;
}
System.out.println("Blah5");
sc2.close();
System.out.println("Welcome to Calculation Program!\n");
startMenus(sc);
}
}
Are you sure you aren't throwing any other exceptions that are killing your app before it reaches System.out.println? Judging by your description you may want to either debug or put some other println statements further up the chain as it could be dying due to something.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class Calculator {
public static int[] NUMBERS; //global value for the array
public static void main(String[] args) throws FileNotFoundException, IOException {
File file = new File("data.txt");
file.createNewFile();
Scanner sc = new Scanner(file);
int counter = 0;
while (sc.hasNextInt()) {
counter = counter++;
}
int lenth = counter;
NUMBERS = new int[lenth];
sc.close();
File file2 = new File("data.txt");
file2.createNewFile();
Scanner sc2 = new Scanner(file2);
int i = 0;
while (sc2.hasNextInt()) {
NUMBERS[i] = sc2.nextInt();
++i;
}
sc2.close();
System.out.println("Welcome to Calculation Program!\n");
startMenus(sc);
}
private static void startMenus(Scanner sc) {
System.out.println("Run your code here!!!");
}
}
Couple of things:
You need to import additional classes that are not part of your core project. Exceptions, File, and Scanner all fall into this category.
You need to run the createNewFile() method to actually create your file. Your original code was throwing a FileNotFound exception because the file was never being created.
You need to have the startMenus method defined before calling it.
I've included some corrected code. Hope this helps!
The System.out calls probably wheren't reached yet, because one of your loops took too long to execute, longer then you were willing to wait. Log something from inside a loop to get some more feedback, the program is probably fine.